[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