[libvirt] PATCH: Write pidfile earlier in startup
Daniel P. Berrange
berrange at redhat.com
Fri May 16 16:39:46 UTC 2008
On Fri, May 16, 2008 at 05:05:08PM +0100, Daniel P. Berrange wrote:
> 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.
There were actually some more changes needed. It needs to write the PID file
even if not running with --daemon mode to be truely safe, because some
init software won't run it in daemon mode at all. So this updated patch will
always write a PID file if run as root. It also fixes a few flaws in the
cleanup process to ensure it only unlinks the pidfile on failure if it owned
the pidfile, and removes a pointless warning when running non-root.
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 16:36:42 -0000
@@ -2143,6 +2143,26 @@ 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;
+ }
+ }
+
+ /* If running as root and no PID file is set, use the default */
+ if (pid_file == NULL &&
+ getuid() == 0 &&
+ REMOTE_PID_FILE[0] != '\0')
+ pid_file = REMOTE_PID_FILE;
+
+ /* If we have a pidfile set, claim it now, exiting if already taken */
+ if (pid_file != NULL &&
+ qemudWritePidFile (pid_file) < 0)
+ goto error1;
+
if (pipe(sigpipe) < 0 ||
qemudSetNonBlock(sigpipe[0]) < 0 ||
qemudSetNonBlock(sigpipe[1]) < 0 ||
@@ -2150,24 +2170,34 @@ int main(int argc, char **argv) {
qemudSetCloseExec(sigpipe[1]) < 0) {
qemudLog(QEMUD_ERR, _("Failed to create pipe: %s"),
strerror(errno));
- goto error1;
+ goto error2;
}
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;
+ goto error2;
}
/* Read the config file (if it exists). */
if (remoteReadConfigFile (server, remote_config_file) < 0)
- goto error1;
+ goto error2;
/* Change the group ownership of /var/run/libvirt to unix_sock_gid */
- if (getuid() != 0) {
- qemudLog (QEMUD_WARN,
- "%s", _("Cannot set group ownership when not running as root"));
- } else {
+ if (getuid() == 0) {
const char *sockdirname = LOCAL_STATE_DIR "/run/libvirt";
if (chown(sockdirname, -1, unix_sock_gid) < 0)
@@ -2175,37 +2205,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,
@@ -2223,19 +2222,17 @@ int main(int argc, char **argv) {
qemudRunLoop(server);
- close(sigwrite);
-
- if (godaemon)
- closelog();
-
ret = 0;
- error2:
- if (godaemon && pid_file)
- unlink (pid_file);
-
- error1:
+error2:
if (server)
qemudCleanup(server);
+ if (pid_file)
+ unlink (pid_file);
+ close(sigwrite);
+
+error1:
+ if (godaemon)
+ closelog();
return ret;
}
--
|: 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 :|
More information about the libvir-list
mailing list