ia64/xen-unstable

changeset 12786:59f438d2739b

Added rudimentary "xend reload" functionality. This allows you to reconfigure
the services offered by Xend, without restarting the daemon itself.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Mon Dec 04 13:37:53 2006 +0000 (2006-12-04)
parents 56d93b6ea9ea
children 3629873ee1e6
files tools/examples/init.d/xend tools/misc/xend tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvServer.py
line diff
     1.1 --- a/tools/examples/init.d/xend	Mon Dec 04 10:27:23 2006 +0000
     1.2 +++ b/tools/examples/init.d/xend	Mon Dec 04 13:37:53 2006 +0000
     1.3 @@ -36,7 +36,10 @@ case "$1" in
     1.4    status)
     1.5  	xend status
     1.6  	;;
     1.7 -  restart|reload|force-reload)
     1.8 +  reload)
     1.9 +        xend reload
    1.10 +        ;;
    1.11 +  restart|force-reload)
    1.12  	xend restart
    1.13  	await_daemons_up
    1.14  	;;
     2.1 --- a/tools/misc/xend	Mon Dec 04 10:27:23 2006 +0000
     2.2 +++ b/tools/misc/xend	Mon Dec 04 13:37:53 2006 +0000
     2.3 @@ -109,7 +109,7 @@ def main():
     2.4      
     2.5      daemon = SrvDaemon.instance()
     2.6      if not sys.argv[1:]:
     2.7 -        print 'usage: %s {start|stop|restart}' % sys.argv[0]
     2.8 +        print 'usage: %s {start|stop|reload|restart}' % sys.argv[0]
     2.9      elif sys.argv[1] == 'start':
    2.10          if os.uname()[0] != "SunOS":
    2.11              start_xenstored()
    2.12 @@ -123,6 +123,8 @@ def main():
    2.13          return daemon.start(trace=1)
    2.14      elif sys.argv[1] == 'stop':
    2.15          return daemon.stop()
    2.16 +    elif sys.argv[1] == 'reload':
    2.17 +        return daemon.reloadConfig()
    2.18      elif sys.argv[1] == 'restart':
    2.19          start_xenstored()
    2.20          start_consoled()
     3.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Mon Dec 04 10:27:23 2006 +0000
     3.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Mon Dec 04 13:37:53 2006 +0000
     3.3 @@ -60,6 +60,14 @@ class Daemon:
     3.4          return running
     3.5  
     3.6  
     3.7 +    def reloadConfig(self):
     3.8 +        """
     3.9 +        """
    3.10 +        pid = read_pid(XEND_PID_FILE)
    3.11 +        if find_process(pid, XEND_PROCESS_NAME):
    3.12 +            os.kill(pid, signal.SIGHUP)
    3.13 +
    3.14 +
    3.15      def status(self):
    3.16          """Returns the status of the xend daemon.
    3.17          The return value is defined by the LSB:
     4.1 --- a/tools/python/xen/xend/server/SrvServer.py	Mon Dec 04 10:27:23 2006 +0000
     4.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Mon Dec 04 13:37:53 2006 +0000
     4.3 @@ -65,6 +65,7 @@ class XendServers:
     4.4      def __init__(self):
     4.5          self.servers = []
     4.6          self.cleaningUp = False
     4.7 +        self.reloadingConfig = False
     4.8  
     4.9      def add(self, server):
    4.10          self.servers.append(server)
    4.11 @@ -78,6 +79,11 @@ class XendServers:
    4.12              except:
    4.13                  pass
    4.14  
    4.15 +    def reloadConfig(self, signum = 0, frame = None):
    4.16 +        log.debug("SrvServer.reloadConfig()")
    4.17 +        self.reloadingConfig = True
    4.18 +        self.cleanup(signum, frame)
    4.19 +
    4.20      def start(self, status):
    4.21          # Running the network script will spawn another process, which takes
    4.22          # the status fd with it unless we set FD_CLOEXEC.  Failing to do this
    4.23 @@ -86,61 +92,71 @@ class XendServers:
    4.24              fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
    4.25          
    4.26          Vifctl.network('start')
    4.27 -        threads = []
    4.28 -        for server in self.servers:
    4.29 -            thread = Thread(target=server.run, name=server.__class__.__name__)
    4.30 -            if isinstance(server, HttpServer):
    4.31 -                thread.setDaemon(True)
    4.32 -            thread.start()
    4.33 -            threads.append(thread)
    4.34 -
    4.35 -
    4.36 -        # check for when all threads have initialized themselves and then
    4.37 -        # close the status pipe
    4.38 -
    4.39 -        threads_left = True
    4.40 -        while threads_left:
    4.41 -            threads_left = False
    4.42 -
    4.43 -            for server in self.servers:
    4.44 -                if not server.ready:
    4.45 -                    threads_left = True
    4.46 -                    break
    4.47 -
    4.48 -            if threads_left:
    4.49 -                time.sleep(.5)
    4.50 -
    4.51 -        if status:
    4.52 -            status.write('0')
    4.53 -            status.close()
    4.54  
    4.55          # Prepare to catch SIGTERM (received when 'xend stop' is executed)
    4.56          # and call each server's cleanup if possible
    4.57          signal.signal(signal.SIGTERM, self.cleanup)
    4.58 +        signal.signal(signal.SIGHUP, self.reloadConfig)
    4.59  
    4.60 -        # Interruptible Thread.join - Python Bug #1167930
    4.61 -        #   Replaces: for t in threads: t.join()
    4.62 -        #   Reason:   The above will cause python signal handlers to be
    4.63 -        #             blocked so we're not able to catch SIGTERM in any
    4.64 -        #             way for cleanup
    4.65 -        runningThreads = threads
    4.66 -        while len(runningThreads) > 0:
    4.67 -            try:
    4.68 -                for t in threads:
    4.69 -                    t.join(1.0)
    4.70 -                runningThreads = [t for t in threads
    4.71 -                                  if t.isAlive() and not t.isDaemon()]
    4.72 -                if self.cleaningUp and len(runningThreads) > 0:
    4.73 -                    log.debug("Waiting for %s." %
    4.74 -                              [x.getName() for x in runningThreads])
    4.75 -            except:
    4.76 -                pass
    4.77 +        while True:
    4.78 +            threads = []
    4.79 +            for server in self.servers:
    4.80 +                thread = Thread(target=server.run, name=server.__class__.__name__)
    4.81 +                if isinstance(server, HttpServer):
    4.82 +                    thread.setDaemon(True)
    4.83 +                thread.start()
    4.84 +                threads.append(thread)
    4.85  
    4.86  
    4.87 -def create():
    4.88 -    root = SrvDir()
    4.89 -    root.putChild('xend', SrvRoot())
    4.90 -    servers = XendServers()
    4.91 +            # check for when all threads have initialized themselves and then
    4.92 +            # close the status pipe
    4.93 +
    4.94 +            threads_left = True
    4.95 +            while threads_left:
    4.96 +                threads_left = False
    4.97 +
    4.98 +                for server in self.servers:
    4.99 +                    if not server.ready:
   4.100 +                        threads_left = True
   4.101 +                        break
   4.102 +
   4.103 +                if threads_left:
   4.104 +                    time.sleep(.5)
   4.105 +
   4.106 +            if status:
   4.107 +                status.write('0')
   4.108 +                status.close()
   4.109 +                status = None
   4.110 +
   4.111 +            # Interruptible Thread.join - Python Bug #1167930
   4.112 +            #   Replaces: for t in threads: t.join()
   4.113 +            #   Reason:   The above will cause python signal handlers to be
   4.114 +            #             blocked so we're not able to catch SIGTERM in any
   4.115 +            #             way for cleanup
   4.116 +            runningThreads = threads
   4.117 +            while len(runningThreads) > 0:
   4.118 +                try:
   4.119 +                    for t in threads:
   4.120 +                        t.join(1.0)
   4.121 +                    runningThreads = [t for t in threads
   4.122 +                                      if t.isAlive() and not t.isDaemon()]
   4.123 +                    if self.cleaningUp and len(runningThreads) > 0:
   4.124 +                        log.debug("Waiting for %s." %
   4.125 +                                  [x.getName() for x in runningThreads])
   4.126 +                except:
   4.127 +                    pass
   4.128 +
   4.129 +            if self.reloadingConfig:
   4.130 +                log.info("Restarting all servers...")
   4.131 +                self.cleaningUp = False
   4.132 +                self.reloadingConfig = False
   4.133 +                xroot.set_config()
   4.134 +                self.servers = []
   4.135 +                _loadConfig(self)
   4.136 +            else:
   4.137 +                break
   4.138 +
   4.139 +def _loadConfig(servers):
   4.140      if xroot.get_xend_http_server():
   4.141          servers.add(HttpServer(root,
   4.142                                 xroot.get_xend_address(),
   4.143 @@ -188,4 +204,11 @@ def create():
   4.144  
   4.145      if xroot.get_xend_unix_xmlrpc_server():
   4.146          servers.add(XMLRPCServer(XendAPI.AUTH_PAM))
   4.147 +
   4.148 +
   4.149 +def create():
   4.150 +    root = SrvDir()
   4.151 +    root.putChild('xend', SrvRoot())
   4.152 +    servers = XendServers()
   4.153 +    _loadConfig(servers)
   4.154      return servers