[libvirt] [PATCH 2/7] virExec: Delay daemonizing as long as possible.

Cole Robinson crobinso at redhat.com
Tue Apr 28 15:31:52 UTC 2009


This way the caller can catch more errors (e.g. from a hook callback) from
the intermediate process.
---
 src/util.c |   56 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/src/util.c b/src/util.c
index 87e215d..47a1cd3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -445,7 +445,7 @@ __virExec(virConnectPtr conn,
     if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
         virReportSystemError(conn, errno,
                              "%s", _("cannot unblock signals"));
-        return -1;
+        _exit(1);
     }
 
     openmax = sysconf (_SC_OPEN_MAX);
@@ -458,31 +458,6 @@ __virExec(virConnectPtr conn,
              !FD_ISSET(i, keepfd)))
             close(i);
 
-    if (flags & VIR_EXEC_DAEMON) {
-        if (setsid() < 0) {
-            virReportSystemError(conn, errno,
-                                 "%s", _("cannot become session leader"));
-            _exit(1);
-        }
-
-        if (chdir("/") < 0) {
-            virReportSystemError(conn, errno,
-                                 "%s", _("cannot change to root directory: %s"));
-            _exit(1);
-        }
-
-        pid = fork();
-        if (pid < 0) {
-            virReportSystemError(conn, errno,
-                                 "%s", _("cannot fork child process"));
-            _exit(1);
-        }
-
-        if (pid > 0)
-            _exit(0);
-    }
-
-
     if (dup2(infd >= 0 ? infd : null, STDIN_FILENO) < 0) {
         virReportSystemError(conn, errno,
                              "%s", _("failed to setup stdin file handle"));
@@ -513,6 +488,33 @@ __virExec(virConnectPtr conn,
     if (hook)
         if ((hook)(data) != 0)
             _exit(1);
+
+    /* Daemonize as late as possible, so the parent process can detect
+     * the above errors with wait* */
+    if (flags & VIR_EXEC_DAEMON) {
+        if (setsid() < 0) {
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot become session leader"));
+            _exit(1);
+        }
+
+        if (chdir("/") < 0) {
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot change to root directory: %s"));
+            _exit(1);
+        }
+
+        pid = fork();
+        if (pid < 0) {
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot fork child process"));
+            _exit(1);
+        }
+
+        if (pid > 0)
+            _exit(0);
+    }
+
     if (envp)
         execve(argv[0], (char **) argv, (char**)envp);
     else
@@ -524,8 +526,6 @@ __virExec(virConnectPtr conn,
 
     _exit(1);
 
-    return 0;
-
  cleanup:
     /* This is cleanup of parent process only - child
        should never jump here on error */
-- 
1.6.2.2




More information about the libvir-list mailing list