From b22d5eebe3bd174446e78f6b64b8d3e7c7f64124 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 14:36:29 -0800 Subject: [PATCH 1/6] The dom destroy path is doing a dom_get on a non-existent domain to ensure it is non-existent. This changes throws an explicit exception when xc_domain_getinfo returns an error, instead of triggering an internal python error. It then handles the exception in dom_get by returning None, which callers already expect to mean failure. Signed-off-by: Robert Read --- tools/python/xen/lowlevel/xc/xc.c | 3 +++ tools/python/xen/xend/XendDomainInfo.py | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 7f398978eb..c7c09efbc1 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -220,6 +220,9 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, return PyErr_NoMemory(); nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info); + + if (nr_doms < 0) + return PyErr_SetFromErrno(xc_error); list = PyList_New(nr_doms); for ( i = 0 ; i < nr_doms; i++ ) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 05edb93be2..b5929ce88b 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -110,9 +110,13 @@ def dom_get(dom): @param dom: domain id @return: info or None """ - domlist = xc.domain_getinfo(dom, 1) - if domlist and dom == domlist[0]['dom']: - return domlist[0] + try: + domlist = xc.domain_getinfo(dom, 1) + if domlist and dom == domlist[0]['dom']: + return domlist[0] + except Exception, err: + # ignore missing domain + log.exception("domain_getinfo(%d) failed, ignoring", dom) return None class XendDomainInfo: From 0def3b0e7f446b7edc733bb890ebad514b201854 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 17:07:33 -0800 Subject: [PATCH 2/6] Disable CONFIG_PNPACPI temporarily in the -xen defconfig (it's known not to work, causing dom0 to fail to boot - see bugzilla for more details). Signed-off-by: Robert Read Signed-off-by: Steven Hand --- linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 05e8e88361..2b7705feba 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -372,7 +372,7 @@ CONFIG_PNP=y # CONFIG_ISAPNP=y # CONFIG_PNPBIOS is not set -CONFIG_PNPACPI=y +# CONFIG_PNPACPI is not set # # Block devices From 590d9c58a14eb1844b49f91498cbe4cfac43cbb6 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 17:45:51 -0800 Subject: [PATCH 3/6] 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 --- tools/misc/xend | 3 -- tools/python/xen/web/httpserver.py | 4 +++ tools/python/xen/xend/server/SrvDaemon.py | 37 ++++++++++++++--------- tools/python/xen/xend/server/SrvServer.py | 22 +++++++++++++- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/tools/misc/xend b/tools/misc/xend index 1777c6488f..e1a6b4f437 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -86,9 +86,6 @@ def main(): daemon = SrvDaemon.instance() if not sys.argv[1:]: print 'usage: %s {start|stop|restart}' % sys.argv[0] - elif os.fork(): - pid, status = os.wait() - return status >> 8 elif sys.argv[1] == 'start': start_xenstored() start_consoled() diff --git a/tools/python/xen/web/httpserver.py b/tools/python/xen/web/httpserver.py index 6c06e44764..394dba2759 100644 --- a/tools/python/xen/web/httpserver.py +++ b/tools/python/xen/web/httpserver.py @@ -273,6 +273,9 @@ class HttpServer: self.interface = interface self.port = port self.root = root + # ready indicates when we are ready to begin accept connections + # it should be set after a successful bind + self.ready = False def getRoot(self): return self.root @@ -283,6 +286,7 @@ class HttpServer: def run(self): self.bind() self.listen() + self.ready = True self.requestLoop() def stop(self): diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index c8fc1ff384..378497e557 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -137,13 +137,6 @@ class Daemon: else: return 0 - def onSIGCHLD(self, signum, frame): - if self.child > 0: - try: - pid, sts = os.waitpid(self.child, os.WNOHANG) - except os.error, ex: - pass - def fork_pid(self, pidfile): """Fork and write the pid of the child to 'pidfile'. @@ -200,15 +193,29 @@ class Daemon: # Trying to run an already-running service is a success. return 0 - signal.signal(signal.SIGCHLD, self.onSIGCHLD) + ret = 0 + + # we use a pipe to communicate between the parent and the child process + # this way we know when the child has actually initialized itself so + # we can avoid a race condition during startup + + r,w = os.pipe() if self.fork_pid(XEND_PID_FILE): - #Parent. Sleep to give child time to start. - time.sleep(1) + os.close(w) + r = os.fdopen(r, 'r') + s = r.read() + r.close() + if not len(s): + ret = 1 + else: + ret = int(s) else: + os.close(r) # Child self.tracing(trace) - self.run() - return 0 + self.run(os.fdopen(w, 'w')) + + return ret def tracing(self, traceon): """Turn tracing on or off. @@ -290,7 +297,7 @@ class Daemon: def stop(self): return self.cleanup(kill=True) - def run(self): + def run(self, status): _enforce_dom0_cpus() try: log.info("Xend Daemon started") @@ -298,12 +305,14 @@ class Daemon: relocate.listenRelocation() servers = SrvServer.create() self.daemonize() - servers.start() + servers.start(status) except Exception, ex: print >>sys.stderr, 'Exception starting xend:', ex if XEND_DEBUG: traceback.print_exc() log.exception("Exception starting xend (%s)" % ex) + status.write('1') + status.close() self.exit(1) def exit(self, rc=0): diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 12a2f5ff5c..ecd4975728 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -48,6 +48,7 @@ from xen.xend import XendRoot; xroot = XendRoot.instance() from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.web.SrvDir import SrvDir +import time from SrvRoot import SrvRoot @@ -59,7 +60,7 @@ class XendServers: def add(self, server): self.servers.append(server) - def start(self): + def start(self, status): Vifctl.network('start') threads = [] for server in self.servers: @@ -67,6 +68,25 @@ class XendServers: thread.start() threads.append(thread) + + # check for when all threads have initialized themselves and then + # close the status pipe + + threads_left = True + while threads_left: + threads_left = False + + for server in self.servers: + if not server.ready: + threads_left = True + break + + if threads_left: + time.sleep(.5) + + status.write('0') + status.close() + for t in threads: t.join() From e739a4d453d6bc578d24dd21a1054e77351075b4 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 17:46:40 -0800 Subject: [PATCH 4/6] O_REUSEADDR is not enough to ensure we don't get address in use errors when xend dies from a signal. We implement a 30 second time to ensure we don't fail if we don't have to. Signed-off-by: Anthony Liguori --- tools/python/xen/web/tcp.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/web/tcp.py b/tools/python/xen/web/tcp.py index ed57d45159..157d059540 100644 --- a/tools/python/xen/web/tcp.py +++ b/tools/python/xen/web/tcp.py @@ -18,6 +18,7 @@ import sys import socket import types +import time from connection import * from protocol import * @@ -35,8 +36,25 @@ class TCPListener(SocketListener): def createSocket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - addr = (self.interface, self.port) - sock.bind(addr) + + # SO_REUSEADDR does not always ensure that we do not get an address + # in use error when restarted quickly + # we implement a timeout to try and avoid failing unnecessarily + + timeout = time.time() + 30 + again = True + while again and time.time() < timeout: + again = False + try: + sock.bind((self.interface, self.port)) + except socket.error, (errno, strerrno): + if errno == 98: + again = True + else: + raise socket.error(errno, strerrno) + if again: + raise socket.error(98, "address in use") + return sock def acceptConnection(self, sock, protocol, addr): From 7de330334af8be7046a67b7ece01c2eb8c9a4782 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 20:12:54 -0800 Subject: [PATCH 5/6] Deal with domain info going away (handle new error path introduced by cset 6828). Believe Dan Smith is working up a more comprehensive patch. Signed-off-by: Steven Hand --- tools/python/xen/xend/XendDomainInfo.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index b5929ce88b..d611bec5a1 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -353,7 +353,12 @@ class XendDomainInfo: def update(self, info=None): """Update with info from xc.domain_getinfo(). """ - self.info = info or dom_get(self.domid) + if info: + self.info = info + else: + di = dom_get(self.domid) + if not di: + return self.memory = self.info['mem_kb'] / 1024 self.ssidref = self.info['ssidref'] From e81e11f6c5863584f4d02db2cfef508bd6f7fd85 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 15 Sep 2005 07:21:31 +0000 Subject: [PATCH 6/6] More build fixes for latest binutils. No 'movl' between a segment register and memory location. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h index 9558ddc045..f7580d3b0c 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h @@ -35,7 +35,7 @@ static inline void __prepare_arch_switch(void) * of cr3/ldt (i.e., not in __switch_to). */ __asm__ __volatile__ ( - "movl %%es,%0 ; movl %%ds,%1 ; movl %%fs,%2 ; movl %%gs,%3" + "mov %%es,%0 ; mov %%ds,%1 ; mov %%fs,%2 ; mov %%gs,%3" : "=m" (current->thread.es), "=m" (current->thread.ds), "=m" (current->thread.fsindex),