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
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?")
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]
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()
#include <errno.h>
#include <malloc.h>
#include <fcntl.h>
+#include <ctype.h>
#include "xcs.h"
#undef fd_max
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;
}
}
}
+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)
{
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;