[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEND] Make XMLRPC Server shutdown cleanly.
# HG changeset patch # User Alastair Tse <atse@xxxxxxxxxxxxx> # Node ID 5fe8e9ebcf5c1da30e0da4e7f66a81de37406dc1 # Parent 52bf7bbb0f363a5d36004c78f501d1dd3270670d [XEND] Make XMLRPC Server shutdown cleanly. We can now catch the end of Xend and clean up domains accordingly. Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx> --- tools/python/xen/xend/server/SrvDaemon.py | 4 + tools/python/xen/xend/server/SrvServer.py | 30 +++++++++++++- tools/python/xen/xend/server/XMLRPCServer.py | 55 +++++++++++++++++++-------- 3 files changed, 70 insertions(+), 19 deletions(-) diff -r 52bf7bbb0f36 -r 5fe8e9ebcf5c tools/python/xen/xend/server/SrvDaemon.py --- a/tools/python/xen/xend/server/SrvDaemon.py Thu Oct 05 17:29:19 2006 +0100 +++ b/tools/python/xen/xend/server/SrvDaemon.py Thu Oct 05 17:29:19 2006 +0100 @@ -195,6 +195,8 @@ class Daemon: sig) else: self.run(w and os.fdopen(w, 'w') or None) + # if we reach here, the child should quit. + os._exit(0) return ret @@ -290,6 +292,8 @@ class Daemon: relocate.listenRelocation() servers = SrvServer.create() servers.start(status) + del servers + except Exception, ex: print >>sys.stderr, 'Exception starting xend:', ex if XEND_DEBUG: diff -r 52bf7bbb0f36 -r 5fe8e9ebcf5c tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py Thu Oct 05 17:29:19 2006 +0100 +++ b/tools/python/xen/xend/server/SrvServer.py Thu Oct 05 17:29:19 2006 +0100 @@ -42,6 +42,7 @@ import fcntl import time +import signal from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer @@ -54,7 +55,6 @@ from SrvRoot import SrvRoot from SrvRoot import SrvRoot from XMLRPCServer import XMLRPCServer - xroot = XendRoot.instance() @@ -65,6 +65,14 @@ class XendServers: def add(self, server): self.servers.append(server) + + def cleanup(self, signum = 0, frame = None): + log.debug("SrvServer.cleanup()") + for server in self.servers: + try: + server.shutdown() + except: + pass def start(self, status): # Running the network script will spawn another process, which takes @@ -100,8 +108,24 @@ class XendServers: status.write('0') status.close() - for t in threads: - t.join() + # Prepare to catch SIGTERM (received when 'xend stop' is executed) + # and call each server's cleanup if possible + signal.signal(signal.SIGTERM, self.cleanup) + + # Interruptible Thread.join - Python Bug #1167930 + # Replaces: for t in threads: t.join() + # Reason: The above will cause python signal handlers to be + # blocked so we're not able to catch SIGTERM in any + # way for cleanup + runningThreads = len([t for t in threads if t.isAlive()]) + while runningThreads > 0: + try: + for t in threads: + t.join(1.0) + runningThreads = len([t for t in threads if t.isAlive()]) + except: + pass + def create(): root = SrvDir() diff -r 52bf7bbb0f36 -r 5fe8e9ebcf5c tools/python/xen/xend/server/XMLRPCServer.py --- a/tools/python/xen/xend/server/XMLRPCServer.py Thu Oct 05 17:29:19 2006 +0100 +++ b/tools/python/xen/xend/server/XMLRPCServer.py Thu Oct 05 17:29:19 2006 +0100 @@ -16,16 +16,15 @@ # Copyright (C) 2006 XenSource Ltd. #============================================================================ +from types import ListType import xmlrpclib - -from xen.xend import XendDomain, XendDomainInfo, XendNode, \ - XendLogging, XendDmesg from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer -from xen.xend.XendClient import XML_RPC_SOCKET, ERROR_INVALID_DOMAIN -from xen.xend.XendError import * +from xen.xend import XendDomain, XendDomainInfo, XendNode +from xen.xend import XendLogging, XendDmesg +from xen.xend.XendClient import XML_RPC_SOCKET from xen.xend.XendLogging import log -from types import ListType +from xen.xend.XendError import XendInvalidDomain def lookup(domid): info = XendDomain.instance().domain_lookup_by_name_or_id(domid) @@ -75,8 +74,8 @@ def get_log(): finally: f.close() -methods = ['device_create', 'device_configure', 'destroyDevice', - 'getDeviceSxprs', +methods = ['device_create', 'device_configure', + 'destroyDevice','getDeviceSxprs', 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', 'send_sysrq', 'getVCPUInfo', 'waitForDevices', 'getRestartCount'] @@ -84,25 +83,33 @@ exclude = ['domain_create', 'domain_rest exclude = ['domain_create', 'domain_restore'] class XMLRPCServer: - def __init__(self, use_tcp=False): - self.ready = False + def __init__(self, use_tcp=False, host = "localhost", port = 8006, + path = XML_RPC_SOCKET): self.use_tcp = use_tcp + self.port = port + self.host = host + self.path = path + + self.ready = False + self.running = True def run(self): if self.use_tcp: - # bind to something fixed for now as we may eliminate - # tcp support completely. - self.server = TCPXMLRPCServer(("localhost", 8005), logRequests=False) + self.server = TCPXMLRPCServer((self.host, self.port), + logRequests = False) else: - self.server = UnixXMLRPCServer(XML_RPC_SOCKET, False) + self.server = UnixXMLRPCServer(self.path, logRequests = False) + + # Legacy deprecated xm xmlrpc api + # -------------------------------------------------------------------- # Functions in XendDomainInfo for name in methods: fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name) self.server.register_function(fn, "xend.domain.%s" % name) - # Functions in XendDomain inst = XendDomain.instance() + for name in dir(inst): fn = getattr(inst, name) if name.startswith("domain_") and callable(fn): @@ -126,4 +133,20 @@ class XMLRPCServer: self.server.register_introspection_functions() self.ready = True - self.server.serve_forever() + + # Custom runloop so we can cleanup when exiting. + # ----------------------------------------------------------------- + try: + self.server.socket.settimeout(1.0) + while self.running: + self.server.handle_request() + finally: + self.cleanup() + + def cleanup(self): + log.debug("XMLRPCServer.cleanup()") + + def shutdown(self): + self.running = False + self.ready = False + _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |