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 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), 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/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/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/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): diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 05edb93be2..d611bec5a1 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: @@ -349,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'] 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()