WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-tools

[Xen-tools] [PATCH] Make daemons more robust

To: Xen Tools <xen-tools@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-tools] [PATCH] Make daemons more robust
From: Anthony Liguori <aliguori@xxxxxxxxxx>
Date: Tue, 09 Aug 2005 22:24:00 -0500
Cc: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Delivery-date: Wed, 10 Aug 2005 03:22:33 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-tools-request@lists.xensource.com?subject=help>
List-id: Xen control tools developers <xen-tools.lists.xensource.com>
List-post: <mailto:xen-tools@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-tools-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 1.0.2 (X11/20050317)
Rusty and I have been working on making the daemon startup be more robust so we don't have the previous timing issues from daemons depending on other daemons. The following patch fixes the xend start issues (where xenstored comes up after xenconsoled) and the xend restart issues (where xenstored becomes unresponsive or has multiple instances running). This also fixes the end-user problems of xm console not working or xend [re]start spitting out an infinite loop of error messages.

The patch implements the following changes:

1) make xenconsoled exit gracefully if xcs dies
2) daemonize xenstored before binding to xenstored socket
3) wait to close stdio in xenstored until we're ready to accept connections (so that PID=`xenstored --output-pid` doesn't return until it's ready to accept connections)
4) updates tools/misc/xend for these changes

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxxx>

Regards,

Anthony Liguori
diff -r 38c7c25b3cb9 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Aug  9 13:53:15 2005
+++ b/tools/console/daemon/io.c Tue Aug  9 22:14:12 2005
@@ -231,6 +231,7 @@
 
                if (!write_sync(xcs_data_fd, &msg, sizeof(msg))) {
                        dolog(LOG_ERR, "Write to xcs failed: %m");
+                       exit(1);
                }
        } else {
                close(dom->tty_fd);
@@ -262,6 +263,7 @@
 
        if (!read_sync(fd, &msg, sizeof(msg))) {
                dolog(LOG_ERR, "read from xcs failed! %m");
+               exit(1);
        } else if (msg.type == XCS_REQUEST) {
                struct domain *dom;
 
diff -r 38c7c25b3cb9 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c      Tue Aug  9 13:53:15 2005
+++ b/tools/console/daemon/utils.c      Tue Aug  9 22:14:12 2005
@@ -59,6 +59,8 @@
 
                if (len < 1) {
                        if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
+                               continue;
+                       } else {
                                return false;
                        }
                } else {
diff -r 38c7c25b3cb9 tools/misc/xend
--- a/tools/misc/xend   Tue Aug  9 13:53:15 2005
+++ b/tools/misc/xend   Tue Aug  9 22:14:12 2005
@@ -24,6 +24,7 @@
 import socket
 import signal
 import time
+import commands
 
 XCS_PATH    = "/var/lib/xen/xcs_socket"
 XCS_EXEC    = "/usr/sbin/xcs"
@@ -116,8 +117,7 @@
        return    
 
 def start_xenstored():
-    if os.fork() == 0:
-        os.execvp('/usr/sbin/xenstored', ['/usr/sbin/xenstored']);
+    s,o = commands.getstatusoutput("/usr/sbin/xenstored 
--pid-file=/var/run/xenstore.pid");
 
 def start_consoled():
     if os.fork() == 0:
diff -r 38c7c25b3cb9 tools/xenstore/utils.c
--- a/tools/xenstore/utils.c    Tue Aug  9 13:53:15 2005
+++ b/tools/xenstore/utils.c    Tue Aug  9 22:14:12 2005
@@ -80,30 +80,6 @@
        barf("malloc of %zu failed", size);
 }
 
-/* Stevens. */
-void daemonize(void)
-{
-       pid_t pid;
-
-       /* Separate from our parent via fork, so init inherits us. */
-       if ((pid = fork()) < 0)
-               barf_perror("Failed to fork daemon");
-       if (pid != 0)
-               exit(0);
-
-       close(STDIN_FILENO);
-       close(STDOUT_FILENO);
-       close(STDERR_FILENO);
-
-       /* Session leader so ^C doesn't whack us. */
-       setsid();
-       /* Move off any mount points we might be in. */
-       chdir("/");
-       /* Discard our parent's old-fashioned umask prejudices. */
-       umask(0);
-}
-
-
 /* This version adds one byte (for nul term) */
 void *grab_file(const char *filename, unsigned long *size)
 {
diff -r 38c7c25b3cb9 tools/xenstore/utils.h
--- a/tools/xenstore/utils.h    Tue Aug  9 13:53:15 2005
+++ b/tools/xenstore/utils.h    Tue Aug  9 22:14:12 2005
@@ -40,9 +40,6 @@
 void *grab_file(const char *filename, unsigned long *size);
 void release_file(void *data, unsigned long size);
 
-/* For writing daemons, based on Stevens. */
-void daemonize(void);
-
 /* Signal handling: returns fd to listen on. */
 int signal_to_fd(int signal);
 void close_signal(int fd);
diff -r 38c7c25b3cb9 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Aug  9 13:53:15 2005
+++ b/tools/xenstore/xenstored_core.c   Tue Aug  9 22:14:12 2005
@@ -1541,10 +1541,49 @@
                            xs_daemon_transactions());
 }
 
+static void write_pidfile(const char *pidfile)
+{
+       char buf[100];
+       int len;
+       int fd;
+
+       fd = open(pidfile, O_RDWR | O_CREAT, 0600);
+       if (fd == -1)
+               barf_perror("Opening pid file %s", pidfile);
+
+       /* We exit silently if daemon already running. */
+       if (lockf(fd, F_TLOCK, 0) == -1)
+               exit(0);
+
+       len = sprintf(buf, "%d\n", getpid());
+       write(fd, buf, len);
+}
+
+/* Stevens. */
+static void daemonize(void)
+{
+       pid_t pid;
+
+       /* Separate from our parent via fork, so init inherits us. */
+       if ((pid = fork()) < 0)
+               barf_perror("Failed to fork daemon");
+       if (pid != 0)
+               exit(0);
+
+       /* Session leader so ^C doesn't whack us. */
+       setsid();
+       /* Move off any mount points we might be in. */
+       chdir("/");
+       /* Discard our parent's old-fashioned umask prejudices. */
+       umask(0);
+}
+
+
 static struct option options[] = { { "no-fork", 0, NULL, 'N' },
                                   { "verbose", 0, NULL, 'V' },
                                   { "output-pid", 0, NULL, 'P' },
                                   { "trace-file", 1, NULL, 'T' },
+                                  { "pid-file", 1, NULL, 'F' },
                                   { NULL, 0, NULL, 0 } };
 
 int main(int argc, char *argv[])
@@ -1554,6 +1593,7 @@
        fd_set inset, outset;
        bool dofork = true;
        bool outputpid = false;
+       const char *pidfile = NULL;
 
        while ((opt = getopt_long(argc, argv, "DVT:", options, NULL)) != -1) {
                switch (opt) {
@@ -1573,10 +1613,19 @@
                                            optarg);
                         write(tracefd, "\n***\n", strlen("\n***\n"));
                        break;
+               case 'F':
+                       pidfile = optarg;
                }
        }
        if (optind != argc)
                barf("%s: No arguments desired", argv[0]);
+
+       if (dofork) {
+               openlog("xenstored", 0, LOG_DAEMON);
+               daemonize();
+       }
+       if (pidfile)
+               write_pidfile(pidfile);
 
        talloc_enable_leak_report_full();
 
@@ -1624,19 +1673,18 @@
        /* Restore existing connections. */
        restore_existing_connections();
 
-       /* Debugging: daemonize() closes standard fds, so dup here. */
-       tmpout = dup(STDOUT_FILENO);
-       if (dofork) {
-               openlog("xenstored", 0, LOG_DAEMON);
-               daemonize();
-       }
-
        if (outputpid) {
                char buffer[20];
                sprintf(buffer, "%i\n", getpid());
                write(tmpout, buffer, strlen(buffer));
        }
-       close(tmpout);
+
+       /* close stdin/stdout now we're ready to accept connections */
+       if (dofork) {
+               close(STDIN_FILENO);
+               close(STDOUT_FILENO);
+               close(STDERR_FILENO);
+       }
 
 #ifdef TESTING
        signal(SIGUSR1, stop_failtest);
_______________________________________________
Xen-tools mailing list
Xen-tools@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-tools
<Prev in Thread] Current Thread [Next in Thread>