bitkeeper revision 1.1236.25.20 (423576ddv67ZIGUBXLyQsmLCTyT6NA)
authorakw27@arcadians.cl.cam.ac.uk <akw27@arcadians.cl.cam.ac.uk>
Mon, 14 Mar 2005 11:34:53 +0000 (11:34 +0000)
committerakw27@arcadians.cl.cam.ac.uk <akw27@arcadians.cl.cam.ac.uk>
Mon, 14 Mar 2005 11:34:53 +0000 (11:34 +0000)
Bunch of little xcs fixes.

Signed-off-by: andrew.warfield@cl.cam.ac.uk
tools/misc/xend
tools/xcs/evtchn.c
tools/xcs/xcs.c

index 4a6a09f29409f4c82680cb2268215dd47298c735..6ad368ca9d292c84df10bb14eca8ce8e8c4bfbd2 100644 (file)
 import os
 import sys
 import socket
+import signal
 import time
 
-XCS_PATH = "/var/lib/xen/xcs_socket"
-XCS_EXEC = "/usr/sbin/xcs"
-XCS_LOGFILE = "/var/log/xcs.log"
+XCS_PATH    = "/var/lib/xen/xcs_socket"
+XCS_EXEC    = "/usr/sbin/xcs"
+XCS_PIDFILE = "/var/run/xcs.pid"
+XCS_ARGS    = (XCS_EXEC, "-p", XCS_PIDFILE)
 
 # Default install path for Xen binary packages.
 sys.path = [ '/usr/lib/python' ] + sys.path
@@ -98,37 +100,21 @@ def check_user():
 
 def xcs_running():
     """ See if the control switch is running.
-    """
-    ret = 1
-    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-    try:
-        s.connect( (XCS_PATH) )
-    except:
-        ret = 0
-    s.close()
-    return (ret)
-    
-def main():
+    """        
     try:
-        check_logging()
-        check_twisted_version()
-        check_user()
-    except CheckError:
-        sys.exit(1)
+       xcs_pidfile = open(XCS_PIDFILE)
+    except IOError:
+       return(0)
+    xcs_pidfile.close()
+    return 1
     
+def start_xcs():
     if (not xcs_running()):
         if os.fork():
-            time.sleep(0.5) # let xcs start
+            time.sleep(0.1) # let xcs start
         else:
             try:
-                logfile = os.open(XCS_LOGFILE, 
-                                  os.O_WRONLY|os.O_APPEND|os.O_CREAT)
-                os.close(1)
-                os.dup(logfile)
-                os.close(2)
-                os.dup(logfile)
-                os.close(logfile)
-                os.execlp(XCS_EXEC, XCS_EXEC)
+                os.execvp(XCS_EXEC, XCS_ARGS)
             except:
                 hline()
                 msg("Tried to start xcs, but failed. Is it installed?")
@@ -139,7 +125,25 @@ def main():
             msg("Failed to start the control interface switch.")
             hline()
             raise CheckError("xcs not running")
-        
+            
+def stop_xcs():
+    try:
+       xcs_pidfile = open(XCS_PIDFILE)
+    except IOError:
+       return
+    xcs_pid = int(xcs_pidfile.read().strip())
+    os.kill(xcs_pid, signal.SIGTERM)
+    xcs_pidfile.close()
+    
+            
+def main():
+    try:
+        check_logging()
+        check_twisted_version()
+        check_user()
+    except CheckError:
+        sys.exit(1)
+    
     daemon = SrvDaemon.instance()
     if not sys.argv[1:]:
         print 'usage: %s {start|stop|restart}' % sys.argv[0]
@@ -147,12 +151,17 @@ def main():
         pid, status = os.wait()
         return status >> 8
     elif sys.argv[1] == 'start':
+        start_xcs()
         return daemon.start()
     elif sys.argv[1] == 'trace_start':
+        start_xcs()
         return daemon.start(trace=1)
     elif sys.argv[1] == 'stop':
+        stop_xcs()
         return daemon.stop()
     elif sys.argv[1] == 'restart':
+        stop_xcs()
+        start_xcs()
         return daemon.stop() or daemon.start()
     elif sys.argv[1] == 'status':
         return daemon.status()
index a96036db37f751dc022a43bedc541888ab57629a..71a297629d7a37bfd0be31fcbe13ef8cd2ad2df8 100644 (file)
@@ -95,8 +95,6 @@ int evtchn_open(void)
             goto reopen;
         return -errno;
     }
-    /*set_cloexec(evtchn_fd); -- no longer required*/
-printf("Eventchan_fd is %d\n", evtchn_fd);
     return evtchn_fd;
 }
 
index 08085d43527d2d15d09bf22c257daecff9b99105..9fb257a43301bd6fe18bd33d8bb53fcd0692090e 100644 (file)
@@ -75,6 +75,7 @@
 #include <errno.h>
 #include <malloc.h>
 #include <fcntl.h>
+#include <ctype.h>
 #include "xcs.h"
 
 #undef fd_max
@@ -250,7 +251,7 @@ static int listen_socket (char *listen_path)
         close (s);
         return -1;
     }
-    printf ("accepting connections on path %s\n", listen_path);
+    DPRINTF ("accepting connections on path %s\n", listen_path);
     listen (s, 10);
     return s;
 }
@@ -628,13 +629,66 @@ void gc_ufd_list( unbound_fd_t **ufd )
     }
 }
 
+void daemonize_xcs(void)
+{
+    
+    /* detach from our controlling tty so that a shell does hang waiting for
+       stopped jobs. */
+    
+    pid_t pid = fork();
+    int fd;
+
+    if (pid == -1) {
+           perror("fork()");
+    } else if (pid) {
+           exit(0);
+    }
+
+    fd = open("/var/log/xcs.log", O_WRONLY | O_APPEND | O_CREAT);
+    if ( fd == -1 ) {
+        fprintf(stderr, "xcs couldn't open logfile.  Directing all output to "
+                "/dev/null instead.\n");
+        fd = open("/dev/null", O_WRONLY);
+    }
+    
+    setsid();
+    close(2);
+    close(1);
+    close(0);
+    dup(fd);
+    dup(fd);
+}
+
+
+static char *pidfilename = NULL;
+void cleanup(int sig)
+{
+    /* throw away our pidfile if we created one. */
+    if ( pidfilename != NULL ) 
+        unlink(pidfilename);
+    exit(0);
+}
+
 int main (int argc, char *argv[])
 {
     int listen_fd, evtchn_fd;
     unbound_fd_t *unbound_fd_list = NULL, **ufd;
     struct timeval timeout = { XCS_GC_INTERVAL, 0 };
     connection_t **con;
+    int c, daemonize;
+    FILE *pidfile;
+    struct stat s;
+    
+    daemonize = 1;
+    pidfile = NULL;
 
+    signal(SIGHUP, cleanup);
+    signal(SIGTERM, cleanup);
+    signal(SIGINT, cleanup);
+    
+    /* Do a bunch of stuff before potentially daemonizing so we can 
+     * print error messages sanely before redirecting output. */
+    
     /* Initialize xc and event connections. */
     if (ctrl_chan_init() != 0)
     {
@@ -648,35 +702,61 @@ int main (int argc, char *argv[])
         exit(-1);
     }
    
+    /* Bind listen_fd to the client socket. */
+    listen_fd = listen_socket(XCS_SUN_PATH);
+     
+    while ((c = getopt (argc, argv, "ip:")) != -1)
+    {
+        switch (c)
+        {
+        case 'i': /* interactive */
+            daemonize = 0;
+            break;
+        case 'p': /* pid file */
+            pidfilename = optarg;
+            break;          
+        case '?':
+            if (isprint (optopt))
+                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+            else
+                fprintf (stderr,
+                    "Bad option character `\\x%x'.\n", optopt);
+            break;
+        }    
+    }
+    
+    if ( pidfilename != NULL )
+    {
+        if ( stat(pidfilename, &s) == 0 )
+        {
+            fprintf(stderr, "Thre specified pid file (%s) already exists.\n"
+                    "Is another instance of xcs running?\n", pidfilename);
+            exit(-1);
+        }
+
+        pidfile = fopen(pidfilename, "w");
+        if (pidfile == NULL)
+        {
+            fprintf(stderr, "Error openning pidfile (%s).\n", pidfilename);
+            exit(-1);
+        }
+    }
+        
+    if (daemonize == 1) 
+        daemonize_xcs();
+    
+    if (pidfile != NULL)
+    {
+        fprintf(pidfile, "%d", getpid());
+        fclose(pidfile); 
+    }
+    
+    
     /* Initialize control interfaces, bindings. */
     init_interfaces();
     init_bindings();
     
-    listen_fd = listen_socket(XCS_SUN_PATH);
    
-    /* detach from our controlling tty so that a shell does hang waiting for
-       stopped jobs. */
-    /* we should use getopt() here */
-
-    if (!(argc == 2 && !strcmp(argv[1], "-i"))) {
-       pid_t pid = fork();
-       int fd;
-
-       if (pid == -1) {
-               perror("fork()");
-       } else if (pid) {
-               exit(0);
-       }
-
-       setsid();
-       close(2);
-       close(1);
-       close(0);
-       fd = open("/dev/null", O_RDWR);
-       dup(fd);
-       dup(fd);
-    }
     for (;;)
     {
         int n = 0, ret;