Skip to contentSkip to conversation

better daemon-ization of xend

PATCH New Charles Coffing 1 participant 1 message Sep 17, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 better daemon-ization of xend

The attached patch tidies up how xend becomes a daemon, and it hooks up the "restart" and "status" commands.

Details:

I attempted to start xend from SuSE's YaST, but YaST hung waiting on xend to start. Turns out that xend wasn't quite becoming a daemon. setsid was conditionally called for xend, and never called for xfrd. Stdin, stdout, and stderr were left open and this is what hung YaST.

Daemon.(start|status) now return LSB-defined error codes. I realize the python scripts are probably meant to be cross platform, but it seemed cleaner to inheirit a few LSB error codes here, rather than create my own and then try to remap them up in /etc/init.d/xend.

I still suspect Linux distributions will write their own /etc/init.d/xend scripts, but at least now the stock one behaves a little better.

tools/misc/xend +5 -2
@@ -8,11 +8,12 @@
    Provides console server and HTTP management api.
 
    Run:
-
    xend start
 
-   The daemon is stopped with:
+   Restart:
+   xend restart
 
+   The daemon is stopped with:
    xend stop
 
    The daemon should reconnect to device control interfaces
@@ -107,6 +108,8 @@
         return daemon.stop()
     elif sys.argv[1] == 'restart':
         return daemon.stop() or daemon.start()
+    elif sys.argv[1] == 'status':
+        return daemon.status()
     else:
         print 'not an option:', sys.argv[1]
     return 1
tools/python/xen/xend/server/SrvDaemon.py +33 -7
@@ -42,7 +42,7 @@
 import domain
 from params import *
 
-DEBUG = 1
+DEBUG = 0
 
 class NotifierProtocol(protocol.Protocol):
     """Asynchronous handler for i/o on the notifier (event channel).
@@ -419,6 +419,18 @@
         self.cleanup_xend(kill=kill)
         self.cleanup_xfrd(kill=kill)
             
+    def status(self):
+        """Returns the status of the xend and xfrd daemons.
+        The return value is defined by the LSB:
+        0  Running
+        3  Not running
+        """
+        if (self.cleanup_process(XEND_PID_FILE, "xend", False) == 0 or
+            self.cleanup_process(XFRD_PID_FILE, "xfrd", False) == 0):
+            return 3
+        else:
+            return 0
+
     def install_child_reaper(self):
         #signal.signal(signal.SIGCHLD, self.onSIGCHLD)
         # Ensure that zombie children are automatically reaped.
@@ -451,22 +463,36 @@
             pass
         else:
             # Child
-            self.set_user()
             os.execl("/usr/sbin/xfrd", "xfrd")
             
     def start(self, trace=0):
+        """Attempts to start the daemons.
+        The return value is defined by the LSB:
+        0  Success
+        4  Insufficient privileges
+        """
         xend_pid = self.cleanup_xend()
         xfrd_pid = self.cleanup_xfrd()
-        if xfrd_pid == 0:
-            self.start_xfrd()
-        if xend_pid > 0:
-            return 1
 
         # Detach from TTY.
         if not DEBUG:
             os.setsid()
+            sys.stdin.close();
+            sys.stdout.close();
+            sys.stderr.close();
+            os.close(0);
+            os.close(1);
+            os.close(2);
         if self.set_user():
-            return 1
+            return 4
+        os.chdir("/")
+
+        if xfrd_pid == 0:
+            self.start_xfrd()
+        if xend_pid > 0:
+            # Trying to run an already-running service is a success.
+            return 0
+
         self.install_child_reaper()
 
         if self.fork_pid(XEND_PID_FILE):
tools/examples/init.d/xend +3 -3
@@ -10,15 +10,15 @@
 case "$1" in
   start)
 	xend start
-	exit $?
 	;;
   stop)
 	xend stop
-	exit $?
 	;;
   status)
+	xend status
 	;;
   restart|reload)
+	xend restart
 	;;
   *)
 	# do not advertise unreasonable commands that there is no reason
@@ -27,5 +27,5 @@
 	exit 1
 esac
 
-exit 0
+exit $?