When used with the --daemon arg, libvirtd will write out a pid file to
/var/run/libvirtd.pid and exit if this file already exists. Unfortuantely
it does this quite late in its startup procedure - in particular *after*
the call to qemudInitialize(), which in turns initializes the drivers,
which in turn autostarts all the VMs and networks.
So if you start a 2nd libvirtd instance it would do autostart before it
got to checking for existing PID file. This is clearly very bad because
the same VM would be started twice resulting in data corruption. Fortunately
the Red Hat / Fedora initscript also checks the PID file before even starting
the daemon, but this can affect people starting the daemon directly.
So this patch makes the goDaemon() / pidfile creation the very first thing
the daemon does after parsing command line arguments. This also results in
greatly increased startup time for OS, since the initscript doesn't have
to wait for it to auto-start all the VMs & networks before it daemonizes.
It also initializes the signal handlers before calling qemudInitialize()
since these really need to be setup before we start any VMs / child procs.
Dan.
Index: qemud/qemud.c
===================================================================
RCS file: /data/cvs/libvirt/qemud/qemud.c,v
retrieving revision 1.100
diff -u -p -r1.100 qemud.c
--- qemud/qemud.c 15 May 2008 06:12:32 -0000 1.100
+++ qemud/qemud.c 16 May 2008 15:58:43 -0000
@@ -2143,6 +2143,24 @@ int main(int argc, char **argv) {
}
}
+ if (godaemon) {
+ openlog("libvirtd", 0, 0);
+ if (qemudGoDaemon() < 0) {
+ qemudLog(QEMUD_ERR, _("Failed to fork as daemon: %s"),
+ strerror(errno));
+ goto error1;
+ }
+
+ /* Choose the name of the PID file. */
+ if (!pid_file) {
+ if (REMOTE_PID_FILE[0] != '\0')
+ pid_file = REMOTE_PID_FILE;
+ }
+
+ if (pid_file && qemudWritePidFile (pid_file) < 0)
+ goto error1;
+ }
+
if (pipe(sigpipe) < 0 ||
qemudSetNonBlock(sigpipe[0]) < 0 ||
qemudSetNonBlock(sigpipe[1]) < 0 ||
@@ -2154,6 +2172,19 @@ int main(int argc, char **argv) {
}
sigwrite = sigpipe[1];
+ sig_action.sa_sigaction = sig_handler;
+ sig_action.sa_flags = SA_SIGINFO;
+ sigemptyset(&sig_action.sa_mask);
+
+ sigaction(SIGHUP, &sig_action, NULL);
+ sigaction(SIGINT, &sig_action, NULL);
+ sigaction(SIGQUIT, &sig_action, NULL);
+ sigaction(SIGTERM, &sig_action, NULL);
+ sigaction(SIGCHLD, &sig_action, NULL);
+
+ sig_action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sig_action, NULL);
+
if (!(server = qemudInitialize(sigpipe[0]))) {
ret = 2;
goto error1;
@@ -2175,37 +2206,6 @@ int main(int argc, char **argv) {
sockdirname);
}
- if (godaemon) {
- openlog("libvirtd", 0, 0);
- if (qemudGoDaemon() < 0) {
- qemudLog(QEMUD_ERR, _("Failed to fork as daemon: %s"),
- strerror(errno));
- goto error1;
- }
-
- /* Choose the name of the PID file. */
- if (!pid_file) {
- if (REMOTE_PID_FILE[0] != '\0')
- pid_file = REMOTE_PID_FILE;
- }
-
- if (pid_file && qemudWritePidFile (pid_file) < 0)
- goto error1;
- }
-
- sig_action.sa_sigaction = sig_handler;
- sig_action.sa_flags = SA_SIGINFO;
- sigemptyset(&sig_action.sa_mask);
-
- sigaction(SIGHUP, &sig_action, NULL);
- sigaction(SIGINT, &sig_action, NULL);
- sigaction(SIGQUIT, &sig_action, NULL);
- sigaction(SIGTERM, &sig_action, NULL);
- sigaction(SIGCHLD, &sig_action, NULL);
-
- sig_action.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sig_action, NULL);
-
if (virEventAddHandleImpl(sigpipe[0],
POLLIN,
qemudDispatchSignalEvent,
--
|: Red Hat, Engineering, Boston -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 :|