There is one caller (virSecurityManagerMetadataLock) which
duplicates the connection FD and wants to have the flag set.
However, trying to set the flag after dup() is not safe as
another thread might fork() meanwhile. Therefore, switch to
duplicating with the flag set and only let callers refine this
later.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/locking/domain_lock.c | 18 ++++++++++++++++++
src/locking/lock_driver_lockd.c | 2 +-
src/rpc/virnetclient.c | 9 +--------
src/rpc/virnetclient.h | 2 +-
4 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c
index 705b132457..db20fa86a3 100644
--- a/src/locking/domain_lock.c
+++ b/src/locking/domain_lock.c
@@ -188,6 +188,24 @@ int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
ret = virLockManagerAcquire(lock, NULL, flags,
dom->def->onLockFailure, fd);
+ if (ret >= 0 && fd && *fd >= 0 && virSetInherit(*fd,
true) < 0) {
+ int saved_errno = errno;
+ virErrorPtr origerr;
+
+ virErrorPreserveLast(&origerr);
+
+ if (virLockManagerRelease(lock, NULL, 0) < 0)
+ VIR_WARN("Unable to release acquired resourced in cleanup path");
+
+ virErrorRestore(&origerr);
+ errno = saved_errno;
+
+ virReportSystemError(errno, "%s",
+ _("Cannot disable close-on-exec flag"));
+
+ ret = -1;
+ }
+
virLockManagerFree(lock);
return ret;
diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c
index 0c672b05b1..9b1943daa6 100644
--- a/src/locking/lock_driver_lockd.c
+++ b/src/locking/lock_driver_lockd.c
@@ -796,7 +796,7 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
goto cleanup;
if (fd &&
- (*fd = virNetClientDupFD(client, false)) < 0)
+ (*fd = virNetClientDupFD(client)) < 0)
goto cleanup;
if (!(flags & VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY)) {
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 40ed3fde6d..6b0ddbeaad 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -712,19 +712,12 @@ int virNetClientGetFD(virNetClientPtr client)
}
-int virNetClientDupFD(virNetClientPtr client, bool cloexec)
+int virNetClientDupFD(virNetClientPtr client)
{
int fd;
virObjectLock(client);
-
fd = virNetSocketDupFD(client->sock);
- if (!cloexec && fd >= 0 && virSetInherit(fd, true)) {
- virReportSystemError(errno, "%s",
- _("Cannot disable close-on-exec flag"));
- VIR_FORCE_CLOSE(fd);
- }
-
virObjectUnlock(client);
return fd;
}
diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h
index 9cf32091f5..3702f7fe5a 100644
--- a/src/rpc/virnetclient.h
+++ b/src/rpc/virnetclient.h
@@ -95,7 +95,7 @@ void virNetClientSetCloseCallback(virNetClientPtr client,
virFreeCallback ff);
int virNetClientGetFD(virNetClientPtr client);
-int virNetClientDupFD(virNetClientPtr client, bool cloexec);
+int virNetClientDupFD(virNetClientPtr client);
bool virNetClientHasPassFD(virNetClientPtr client);
--
2.16.4