On Tue, Apr 28, 2009 at 11:31:52AM -0400, Cole Robinson wrote:
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 */
--
ACK
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|