direct-io.hg

changeset 6830:7985a4d8bae9

Make sure xend start doesn't return until xend is ready to accept connections.

This means xend start && xm list actually works now (instead of throwing an
exception).

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
author shand@ubuntu.eng.hq.xensource.com
date Wed Sep 14 17:45:51 2005 -0800 (2005-09-14)
parents 3a79e8b28999
children 36f8c5900e86
files tools/misc/xend tools/python/xen/web/httpserver.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvServer.py
line diff
     1.1 --- a/tools/misc/xend	Wed Sep 14 17:07:33 2005 -0800
     1.2 +++ b/tools/misc/xend	Wed Sep 14 17:45:51 2005 -0800
     1.3 @@ -86,9 +86,6 @@ def main():
     1.4      daemon = SrvDaemon.instance()
     1.5      if not sys.argv[1:]:
     1.6          print 'usage: %s {start|stop|restart}' % sys.argv[0]
     1.7 -    elif os.fork():
     1.8 -        pid, status = os.wait()
     1.9 -        return status >> 8
    1.10      elif sys.argv[1] == 'start':
    1.11          start_xenstored()
    1.12          start_consoled()
     2.1 --- a/tools/python/xen/web/httpserver.py	Wed Sep 14 17:07:33 2005 -0800
     2.2 +++ b/tools/python/xen/web/httpserver.py	Wed Sep 14 17:45:51 2005 -0800
     2.3 @@ -273,6 +273,9 @@ class HttpServer:
     2.4          self.interface = interface
     2.5          self.port = port
     2.6          self.root = root
     2.7 +        # ready indicates when we are ready to begin accept connections
     2.8 +        # it should be set after a successful bind
     2.9 +        self.ready = False
    2.10  
    2.11      def getRoot(self):
    2.12          return self.root
    2.13 @@ -283,6 +286,7 @@ class HttpServer:
    2.14      def run(self):
    2.15          self.bind()
    2.16          self.listen()
    2.17 +        self.ready = True
    2.18          self.requestLoop()
    2.19  
    2.20      def stop(self):
     3.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Sep 14 17:07:33 2005 -0800
     3.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Sep 14 17:45:51 2005 -0800
     3.3 @@ -137,13 +137,6 @@ class Daemon:
     3.4          else:
     3.5              return 0
     3.6  
     3.7 -    def onSIGCHLD(self, signum, frame):
     3.8 -        if self.child > 0: 
     3.9 -            try: 
    3.10 -                pid, sts = os.waitpid(self.child, os.WNOHANG)
    3.11 -            except os.error, ex:
    3.12 -                pass
    3.13 -
    3.14      def fork_pid(self, pidfile):
    3.15          """Fork and write the pid of the child to 'pidfile'.
    3.16  
    3.17 @@ -200,15 +193,29 @@ class Daemon:
    3.18              # Trying to run an already-running service is a success.
    3.19              return 0
    3.20  
    3.21 -        signal.signal(signal.SIGCHLD, self.onSIGCHLD)
    3.22 +        ret = 0
    3.23 +
    3.24 +        # we use a pipe to communicate between the parent and the child process
    3.25 +        # this way we know when the child has actually initialized itself so
    3.26 +        # we can avoid a race condition during startup
    3.27 +        
    3.28 +        r,w = os.pipe()
    3.29          if self.fork_pid(XEND_PID_FILE):
    3.30 -            #Parent. Sleep to give child time to start.
    3.31 -            time.sleep(1)
    3.32 +            os.close(w)
    3.33 +            r = os.fdopen(r, 'r')
    3.34 +            s = r.read()
    3.35 +            r.close()
    3.36 +            if not len(s):
    3.37 +                ret = 1
    3.38 +            else:
    3.39 +                ret = int(s)
    3.40          else:
    3.41 +            os.close(r)
    3.42              # Child
    3.43              self.tracing(trace)
    3.44 -            self.run()
    3.45 -        return 0
    3.46 +            self.run(os.fdopen(w, 'w'))
    3.47 +
    3.48 +        return ret
    3.49  
    3.50      def tracing(self, traceon):
    3.51          """Turn tracing on or off.
    3.52 @@ -290,7 +297,7 @@ class Daemon:
    3.53      def stop(self):
    3.54          return self.cleanup(kill=True)
    3.55  
    3.56 -    def run(self):
    3.57 +    def run(self, status):
    3.58          _enforce_dom0_cpus()
    3.59          try:
    3.60              log.info("Xend Daemon started")
    3.61 @@ -298,12 +305,14 @@ class Daemon:
    3.62              relocate.listenRelocation()
    3.63              servers = SrvServer.create()
    3.64              self.daemonize()
    3.65 -            servers.start()
    3.66 +            servers.start(status)
    3.67          except Exception, ex:
    3.68              print >>sys.stderr, 'Exception starting xend:', ex
    3.69              if XEND_DEBUG:
    3.70                  traceback.print_exc()
    3.71              log.exception("Exception starting xend (%s)" % ex)
    3.72 +            status.write('1')
    3.73 +            status.close()
    3.74              self.exit(1)
    3.75              
    3.76      def exit(self, rc=0):
     4.1 --- a/tools/python/xen/xend/server/SrvServer.py	Wed Sep 14 17:07:33 2005 -0800
     4.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Wed Sep 14 17:45:51 2005 -0800
     4.3 @@ -48,6 +48,7 @@ from xen.xend import XendRoot; xroot = X
     4.4  from xen.xend import Vifctl
     4.5  from xen.xend.XendLogging import log
     4.6  from xen.web.SrvDir import SrvDir
     4.7 +import time
     4.8  
     4.9  from SrvRoot import SrvRoot
    4.10  
    4.11 @@ -59,7 +60,7 @@ class XendServers:
    4.12      def add(self, server):
    4.13          self.servers.append(server)
    4.14  
    4.15 -    def start(self):
    4.16 +    def start(self, status):
    4.17          Vifctl.network('start')
    4.18          threads = []
    4.19          for server in self.servers:
    4.20 @@ -67,6 +68,25 @@ class XendServers:
    4.21              thread.start()
    4.22              threads.append(thread)
    4.23  
    4.24 +
    4.25 +        # check for when all threads have initialized themselves and then
    4.26 +        # close the status pipe
    4.27 +
    4.28 +        threads_left = True
    4.29 +        while threads_left:
    4.30 +            threads_left = False
    4.31 +
    4.32 +            for server in self.servers:
    4.33 +                if not server.ready:
    4.34 +                    threads_left = True
    4.35 +                    break
    4.36 +
    4.37 +            if threads_left:
    4.38 +                time.sleep(.5)
    4.39 +
    4.40 +        status.write('0')
    4.41 +        status.close()
    4.42 +
    4.43          for t in threads:
    4.44              t.join()
    4.45