From 5314dffc8595c493c652a2174857a065b2841c0a Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Mon, 4 May 2009 15:43:25 +0000 Subject: [PATCH] virExec: Delay daemonizing as long as possible. This way the caller can catch more errors (e.g. from a hook callback) from the intermediate process. --- ChangeLog | 4 ++++ src/util.c | 56 +++++++++++++++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee66a04129..d4de10924e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Mon May 4 11:42:01 EDT 2009 Cole Robinson + + * src/util.c: virExec: Delay daemonizing as long as possible. + Mon May 4 11:40:27 EDT 2009 Cole Robinson * src/util.c: Add some documentation to __virExec and virExec diff --git a/src/util.c b/src/util.c index 87e215d477..47a1cd3f45 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 */