[Pkg-libvirt-commits] [SCM] Libvirt Debian packaging branch, master, updated. debian/0.7.1-2-11-g43b7dac

Laurent Léonard laurent at open-minds.org
Sun Oct 25 00:20:03 UTC 2009


The following commit has been merged in the master branch:
commit 43b7dacb9e9c8f988a2ecb2155e4ecf2f3fd5c6d
Author: Laurent Léonard <laurent at open-minds.org>
Date:   Sun Oct 25 02:19:04 2009 +0200

    Don't let parent of daemon exit until basic initialization is done.

diff --git a/debian/patches/0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch b/debian/patches/0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch
new file mode 100644
index 0000000..5b5935e
--- /dev/null
+++ b/debian/patches/0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch
@@ -0,0 +1,233 @@
+From: =?utf-8?q?Laurent=20L=C3=A9onard?= <laurent at open-minds.org>
+Date: Sun, 25 Oct 2009 01:36:36 +0200
+Subject: [PATCH] Don't let parent of daemon exit until basic initialization is done.
+
+---
+ daemon/libvirtd.c |  116 +++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 files changed, 99 insertions(+), 17 deletions(-)
+
+diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
+index 78dfb2d..d102c66 100644
+--- a/daemon/libvirtd.c
++++ b/daemon/libvirtd.c
+@@ -185,6 +185,30 @@ static int max_client_requests = 5;
+ static sig_atomic_t sig_errors = 0;
+ static int sig_lasterrno = 0;
+ 
++enum {
++    VIR_DAEMON_ERR_NONE = 0,
++    VIR_DAEMON_ERR_PIDFILE,
++    VIR_DAEMON_ERR_RUNDIR,
++    VIR_DAEMON_ERR_INIT,
++    VIR_DAEMON_ERR_SIGNAL,
++    VIR_DAEMON_ERR_PRIVS,
++    VIR_DAEMON_ERR_NETWORK,
++    VIR_DAEMON_ERR_CONFIG,
++
++    VIR_DAEMON_ERR_LAST
++};
++
++VIR_ENUM_DECL(virDaemonErr)
++VIR_ENUM_IMPL(virDaemonErr, VIR_DAEMON_ERR_LAST,
++              "Initialization successful",
++              "Unable to obtain pidfile",
++              "Unable to create rundir",
++              "Unable to initialize libvirt",
++              "Unable to setup signal handlers",
++              "Unable to drop privileges",
++              "Unable to initialize network sockets",
++              "Unable to load configuration file")
++
+ static void sig_handler(int sig, siginfo_t * siginfo,
+                         void* context ATTRIBUTE_UNUSED) {
+     int origerrno;
+@@ -375,7 +399,11 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
+ }
+ 
+ 
+-static int qemudGoDaemon(void) {
++static int daemonForkIntoBackground(void) {
++    int statuspipe[2];
++    if (pipe(statuspipe) < 0)
++        return -1;
++
+     int pid = fork();
+     switch (pid) {
+     case 0:
+@@ -384,6 +412,8 @@ static int qemudGoDaemon(void) {
+             int stdoutfd = -1;
+             int nextpid;
+ 
++            close(statuspipe[0]);
++
+             if ((stdinfd = open("/dev/null", O_RDONLY)) < 0)
+                 goto cleanup;
+             if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0)
+@@ -407,7 +437,7 @@ static int qemudGoDaemon(void) {
+             nextpid = fork();
+             switch (nextpid) {
+             case 0:
+-                return 0;
++                return statuspipe[1];
+             case -1:
+                 return -1;
+             default:
+@@ -428,15 +458,29 @@ static int qemudGoDaemon(void) {
+ 
+     default:
+         {
+-            int got, status = 0;
+-            /* We wait to make sure the next child forked
+-               successfully */
+-            if ((got = waitpid(pid, &status, 0)) < 0 ||
++            int got, exitstatus = 0;
++            int ret;
++            char status;
++
++            close(statuspipe[1]);
++
++            /* We wait to make sure the first child forked successfully */
++            if ((got = waitpid(pid, &exitstatus, 0)) < 0 ||
+                 got != pid ||
+                 status != 0) {
+                 return -1;
+             }
+-            _exit(0);
++
++            /* Now block until the second child initializes successfully */
++        again:
++            ret = read(statuspipe[0], &status, 1);
++            if (ret == -1 && errno == EINTR)
++                goto again;
++
++            if (ret == 1 && status != 0) {
++                fprintf(stderr, "error: %s\n", virDaemonErrTypeToString(status));
++            }
++            _exit(ret == 1 && status == 0 ? 0 : 1);
+         }
+     }
+ }
+@@ -859,8 +903,6 @@ static struct qemud_server *qemudInitialize(int sigread) {
+                          virEventUpdateTimeoutImpl,
+                          virEventRemoveTimeoutImpl);
+ 
+-    virStateInitialize(server->privileged);
+-
+     return server;
+ }
+ 
+@@ -2842,6 +2884,7 @@ int main(int argc, char **argv) {
+     int sigpipe[2];
+     const char *pid_file = NULL;
+     const char *remote_config_file = NULL;
++    int statuswrite = -1;
+     int ret = 1;
+ 
+     struct option opts[] = {
+@@ -2923,7 +2966,7 @@ int main(int argc, char **argv) {
+ 
+     if (godaemon) {
+         char ebuf[1024];
+-        if (qemudGoDaemon() < 0) {
++        if ((statuswrite = daemonForkIntoBackground()) < 0) {
+             VIR_ERROR(_("Failed to fork as daemon: %s"),
+                       virStrerror(errno, ebuf, sizeof ebuf));
+             goto error1;
+@@ -2938,8 +2981,11 @@ int main(int argc, char **argv) {
+ 
+     /* If we have a pidfile set, claim it now, exiting if already taken */
+     if (pid_file != NULL &&
+-        qemudWritePidFile (pid_file) < 0)
++        qemudWritePidFile (pid_file) < 0) {
++        pid_file = NULL; /* Prevent unlinking of someone else's pid ! */
++        ret = VIR_DAEMON_ERR_PIDFILE;
+         goto error1;
++    }
+ 
+     if (pipe(sigpipe) < 0 ||
+         virSetNonBlock(sigpipe[0]) < 0 ||
+@@ -2973,7 +3019,8 @@ int main(int argc, char **argv) {
+         if (mkdir (rundir, 0755)) {
+             if (errno != EEXIST) {
+                 VIR_ERROR0 (_("unable to create rundir"));
+-                return -1;
++                ret = VIR_DAEMON_ERR_RUNDIR;
++                goto error1;
+             }
+         }
+     }
+@@ -2984,17 +3031,21 @@ int main(int argc, char **argv) {
+      * which is also passed into all libvirt stateful
+      * drivers
+      */
+-    if (qemudSetupPrivs() < 0)
++    if (qemudSetupPrivs() < 0) {
++        ret = VIR_DAEMON_ERR_PRIVS;
+         goto error2;
++    }
+ 
+     if (!(server = qemudInitialize(sigpipe[0]))) {
+-        ret = 2;
++        ret = VIR_DAEMON_ERR_INIT;
+         goto error2;
+     }
+ 
+     /* Read the config file (if it exists). */
+-    if (remoteReadConfigFile (server, remote_config_file) < 0)
++    if (remoteReadConfigFile (server, remote_config_file) < 0) {
++        ret = VIR_DAEMON_ERR_CONFIG;
+         goto error2;
++    }
+ 
+     /* Change the group ownership of /var/run/libvirt to unix_sock_gid */
+     if (unix_sock_dir && server->privileged) {
+@@ -3013,15 +3064,46 @@ int main(int argc, char **argv) {
+     }
+ 
+     if (!(server = qemudNetworkInit(server))) {
+-        ret = 2;
++        ret = VIR_DAEMON_ERR_NETWORK;
+         goto error2;
+     }
+ 
+-    qemudRunLoop(server);
++    /* Tell parent of daemon that basic initialization is complete
++     * In particular we're ready to accept net connections & have
++     * written the pidfile
++     */
++    if (statuswrite != -1) {
++        char status = 0;
++        while (write(statuswrite, &status, 1) == -1 &&
++               errno == EINTR)
++            ;
++        close(statuswrite);
++        statuswrite = -1;
++    }
++
++    /* Start the stateful HV drivers
++     * This is delibrately done after telling the parent process
++     * we're ready, since it can take a long time and this will
++     * seriously delay OS bootup process */
++    if (virStateInitialize(server->privileged) < 0) {
++        VIR_ERROR0("Driver state initialization failed");
++        goto error2;
++    }
+ 
++    qemudRunLoop(server);
+     ret = 0;
+ 
+ error2:
++    if (statuswrite != -1) {
++        if (ret != 0) {
++            /* Tell parent of daemon what failed */
++            char status = ret;
++            while (write(statuswrite, &status, 1) == -1 &&
++                   errno == EINTR)
++                ;
++        }
++        close(statuswrite);
++    }
+     if (server)
+         qemudCleanup(server);
+     if (pid_file)
+-- 
diff --git a/debian/patches/series b/debian/patches/series
index 8926c3c..77ea202 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@
 0003-allow-libvirt-group-to-access-the-socket.patch
 0004-fix-Debian-specific-path-to-hvm-loader.patch
 0005-Fix-SELinux-linking-issues.patch
+0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch

-- 
Libvirt Debian packaging



More information about the Pkg-libvirt-commits mailing list