ia64/xen-unstable

changeset 6086:ee68821f4e9c

Make xen daemon startup more robust.
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@us.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustycorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Wed Aug 10 09:46:51 2005 +0000 (2005-08-10)
parents 66b81b6c096c
children 66e6479d9ab8
files tools/console/daemon/io.c tools/console/daemon/utils.c tools/misc/xend tools/xenstore/utils.c tools/xenstore/utils.h tools/xenstore/xenstored_core.c
line diff
     1.1 --- a/tools/console/daemon/io.c	Wed Aug 10 08:44:58 2005 +0000
     1.2 +++ b/tools/console/daemon/io.c	Wed Aug 10 09:46:51 2005 +0000
     1.3 @@ -231,6 +231,7 @@ static void handle_tty_read(struct domai
     1.4  
     1.5  		if (!write_sync(xcs_data_fd, &msg, sizeof(msg))) {
     1.6  			dolog(LOG_ERR, "Write to xcs failed: %m");
     1.7 +			exit(1);
     1.8  		}
     1.9  	} else {
    1.10  		close(dom->tty_fd);
    1.11 @@ -262,6 +263,7 @@ static void handle_xcs_msg(int fd)
    1.12  
    1.13  	if (!read_sync(fd, &msg, sizeof(msg))) {
    1.14  		dolog(LOG_ERR, "read from xcs failed! %m");
    1.15 +		exit(1);
    1.16  	} else if (msg.type == XCS_REQUEST) {
    1.17  		struct domain *dom;
    1.18  
     2.1 --- a/tools/console/daemon/utils.c	Wed Aug 10 08:44:58 2005 +0000
     2.2 +++ b/tools/console/daemon/utils.c	Wed Aug 10 09:46:51 2005 +0000
     2.3 @@ -59,6 +59,8 @@ bool _read_write_sync(int fd, void *data
     2.4  
     2.5  		if (len < 1) {
     2.6  			if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
     2.7 +				continue;
     2.8 +			} else {
     2.9  				return false;
    2.10  			}
    2.11  		} else {
     3.1 --- a/tools/misc/xend	Wed Aug 10 08:44:58 2005 +0000
     3.2 +++ b/tools/misc/xend	Wed Aug 10 09:46:51 2005 +0000
     3.3 @@ -24,6 +24,7 @@ import sys
     3.4  import socket
     3.5  import signal
     3.6  import time
     3.7 +import commands
     3.8  
     3.9  XCS_PATH    = "/var/lib/xen/xcs_socket"
    3.10  XCS_EXEC    = "/usr/sbin/xcs"
    3.11 @@ -116,8 +117,7 @@ def stop_xcs():
    3.12  	return    
    3.13  
    3.14  def start_xenstored():
    3.15 -    if os.fork() == 0:
    3.16 -        os.execvp('/usr/sbin/xenstored', ['/usr/sbin/xenstored']);
    3.17 +    s,o = commands.getstatusoutput("/usr/sbin/xenstored --pid-file=/var/run/xenstore.pid");
    3.18  
    3.19  def start_consoled():
    3.20      if os.fork() == 0:
     4.1 --- a/tools/xenstore/utils.c	Wed Aug 10 08:44:58 2005 +0000
     4.2 +++ b/tools/xenstore/utils.c	Wed Aug 10 09:46:51 2005 +0000
     4.3 @@ -80,30 +80,6 @@ void *malloc_nofail(size_t size)
     4.4  	barf("malloc of %zu failed", size);
     4.5  }
     4.6  
     4.7 -/* Stevens. */
     4.8 -void daemonize(void)
     4.9 -{
    4.10 -	pid_t pid;
    4.11 -
    4.12 -	/* Separate from our parent via fork, so init inherits us. */
    4.13 -	if ((pid = fork()) < 0)
    4.14 -		barf_perror("Failed to fork daemon");
    4.15 -	if (pid != 0)
    4.16 -		exit(0);
    4.17 -
    4.18 -	close(STDIN_FILENO);
    4.19 -	close(STDOUT_FILENO);
    4.20 -	close(STDERR_FILENO);
    4.21 -
    4.22 -	/* Session leader so ^C doesn't whack us. */
    4.23 -	setsid();
    4.24 -	/* Move off any mount points we might be in. */
    4.25 -	chdir("/");
    4.26 -	/* Discard our parent's old-fashioned umask prejudices. */
    4.27 -	umask(0);
    4.28 -}
    4.29 -
    4.30 -
    4.31  /* This version adds one byte (for nul term) */
    4.32  void *grab_file(const char *filename, unsigned long *size)
    4.33  {
     5.1 --- a/tools/xenstore/utils.h	Wed Aug 10 08:44:58 2005 +0000
     5.2 +++ b/tools/xenstore/utils.h	Wed Aug 10 09:46:51 2005 +0000
     5.3 @@ -40,9 +40,6 @@ void barf_perror(const char *fmt, ...) _
     5.4  void *grab_file(const char *filename, unsigned long *size);
     5.5  void release_file(void *data, unsigned long size);
     5.6  
     5.7 -/* For writing daemons, based on Stevens. */
     5.8 -void daemonize(void);
     5.9 -
    5.10  /* Signal handling: returns fd to listen on. */
    5.11  int signal_to_fd(int signal);
    5.12  void close_signal(int fd);
     6.1 --- a/tools/xenstore/xenstored_core.c	Wed Aug 10 08:44:58 2005 +0000
     6.2 +++ b/tools/xenstore/xenstored_core.c	Wed Aug 10 09:46:51 2005 +0000
     6.3 @@ -1540,10 +1540,49 @@ static void setup_structure(void)
     6.4  			    xs_daemon_transactions());
     6.5  }
     6.6  
     6.7 +static void write_pidfile(const char *pidfile)
     6.8 +{
     6.9 +	char buf[100];
    6.10 +	int len;
    6.11 +	int fd;
    6.12 +
    6.13 +	fd = open(pidfile, O_RDWR | O_CREAT, 0600);
    6.14 +	if (fd == -1)
    6.15 +		barf_perror("Opening pid file %s", pidfile);
    6.16 +
    6.17 +	/* We exit silently if daemon already running. */
    6.18 +	if (lockf(fd, F_TLOCK, 0) == -1)
    6.19 +		exit(0);
    6.20 +
    6.21 +	len = sprintf(buf, "%d\n", getpid());
    6.22 +	write(fd, buf, len);
    6.23 +}
    6.24 +
    6.25 +/* Stevens. */
    6.26 +static void daemonize(void)
    6.27 +{
    6.28 +	pid_t pid;
    6.29 +
    6.30 +	/* Separate from our parent via fork, so init inherits us. */
    6.31 +	if ((pid = fork()) < 0)
    6.32 +		barf_perror("Failed to fork daemon");
    6.33 +	if (pid != 0)
    6.34 +		exit(0);
    6.35 +
    6.36 +	/* Session leader so ^C doesn't whack us. */
    6.37 +	setsid();
    6.38 +	/* Move off any mount points we might be in. */
    6.39 +	chdir("/");
    6.40 +	/* Discard our parent's old-fashioned umask prejudices. */
    6.41 +	umask(0);
    6.42 +}
    6.43 +
    6.44 +
    6.45  static struct option options[] = { { "no-fork", 0, NULL, 'N' },
    6.46  				   { "verbose", 0, NULL, 'V' },
    6.47  				   { "output-pid", 0, NULL, 'P' },
    6.48  				   { "trace-file", 1, NULL, 'T' },
    6.49 +				   { "pid-file", 1, NULL, 'F' },
    6.50  				   { NULL, 0, NULL, 0 } };
    6.51  
    6.52  int main(int argc, char *argv[])
    6.53 @@ -1553,6 +1592,7 @@ int main(int argc, char *argv[])
    6.54  	fd_set inset, outset;
    6.55  	bool dofork = true;
    6.56  	bool outputpid = false;
    6.57 +	const char *pidfile = NULL;
    6.58  
    6.59  	while ((opt = getopt_long(argc, argv, "DVT:", options, NULL)) != -1) {
    6.60  		switch (opt) {
    6.61 @@ -1572,11 +1612,20 @@ int main(int argc, char *argv[])
    6.62  					    optarg);
    6.63                          write(tracefd, "\n***\n", strlen("\n***\n"));
    6.64  			break;
    6.65 +		case 'F':
    6.66 +			pidfile = optarg;
    6.67  		}
    6.68  	}
    6.69  	if (optind != argc)
    6.70  		barf("%s: No arguments desired", argv[0]);
    6.71  
    6.72 +	if (dofork) {
    6.73 +		openlog("xenstored", 0, LOG_DAEMON);
    6.74 +		daemonize();
    6.75 +	}
    6.76 +	if (pidfile)
    6.77 +		write_pidfile(pidfile);
    6.78 +
    6.79  	talloc_enable_leak_report_full();
    6.80  
    6.81  	/* Create sockets for them to listen to. */
    6.82 @@ -1623,19 +1672,18 @@ int main(int argc, char *argv[])
    6.83  	/* Restore existing connections. */
    6.84  	restore_existing_connections();
    6.85  
    6.86 -	/* Debugging: daemonize() closes standard fds, so dup here. */
    6.87 -	tmpout = dup(STDOUT_FILENO);
    6.88 -	if (dofork) {
    6.89 -		openlog("xenstored", 0, LOG_DAEMON);
    6.90 -		daemonize();
    6.91 -	}
    6.92 -
    6.93  	if (outputpid) {
    6.94  		char buffer[20];
    6.95  		sprintf(buffer, "%i\n", getpid());
    6.96  		write(tmpout, buffer, strlen(buffer));
    6.97  	}
    6.98 -	close(tmpout);
    6.99 +
   6.100 +	/* close stdin/stdout now we're ready to accept connections */
   6.101 +	if (dofork) {
   6.102 +		close(STDIN_FILENO);
   6.103 +		close(STDOUT_FILENO);
   6.104 +		close(STDERR_FILENO);
   6.105 +	}
   6.106  
   6.107  #ifdef TESTING
   6.108  	signal(SIGUSR1, stop_failtest);