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
|