WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Merge the child-process handling of the save and restore

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Merge the child-process handling of the save and restore functions into one
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 04 Oct 2005 17:02:10 +0000
Delivery-date: Tue, 04 Oct 2005 16:59:41 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User emellor@ewan
# Node ID bc325488f47f7bf986a7c3a5e106d4db1a68d68e
# Parent  84c585a99a7b14de177567db8eee812ee7cd46c5
Merge the child-process handling of the save and restore functions into one
forkHelper function.  Change the handling of file descriptor closure to wait
until both stdout and stderr descriptors have closed.  This may fix the
intermittent bug seen whereby xm restore; xend restart leaves the domain in a
misconfigured state, presumably because IntroduceDomain is not being called by
XendCheckpoint.restore.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r 84c585a99a7b -r bc325488f47f tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Tue Oct  4 15:38:04 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Tue Oct  4 16:49:52 2005
@@ -8,8 +8,8 @@
 import os
 import re
 import select
+import string
 import sxp
-from string import join
 from struct import pack, unpack, calcsize
 
 from xen.util.xpopen import xPopen3
@@ -65,40 +65,22 @@
         # more information.
         cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
                str(dominfo.getDomid()), "0", "0", str(int(live)) ]
-        log.info("[xc_save] " + join(cmd))
-        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
-    
-        lasterr = ""
-        p = select.poll()
-        p.register(child.fromchild.fileno())
-        p.register(child.childerr.fileno())
-        while True: 
-            r = p.poll()
-            for (fd, event) in r:
-                if not event & select.POLLIN:
-                    continue
-                if fd == child.childerr.fileno():
-                    l = child.childerr.readline()
-                    log.error(l.rstrip())
-                    lasterr = l.rstrip()
-                if fd == child.fromchild.fileno():
-                    l = child.fromchild.readline()
-                    if l.rstrip() == "suspend":
-                        log.info("suspending %d", dominfo.getDomid())
-                        dominfo.shutdown('suspend')
-                        dominfo.waitForShutdown()
-                        log.info("suspend %d done", dominfo.getDomid())
-                        child.tochild.write("done\n")
-                        child.tochild.flush()
-            if filter(lambda (fd, event): event & select.POLLHUP, r):
-                break
+        log.debug("[xc_save]: %s", string.join(cmd))
 
-        if child.wait() >> 8 == 127:
-            lasterr = "popen %s failed" % PATH_XC_SAVE
-        if child.wait() != 0:
-            raise XendError("xc_save failed: %s" % lasterr)
+        def saveInputHandler(line, tochild):
+            log.debug("In saveInputHandler %s", line)
+            if line == "suspend":
+                log.debug("Suspending %d ...", dominfo.getDomid())
+                dominfo.shutdown('suspend')
+                dominfo.waitForShutdown()
+                log.info("Domain %d suspended.", dominfo.getDomid())
+                tochild.write("done\n")
+                tochild.flush()
+
+        forkHelper(cmd, fd, saveInputHandler, False)
 
         dominfo.destroyDomain()
+
     except Exception, exn:
         log.exception("Save failed on domain %s (%d).", domain_name,
                       dominfo.getDomid())
@@ -149,52 +131,66 @@
         cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
                str(dominfo.getDomid()), str(nr_pfns),
                str(store_evtchn), str(console_evtchn)]
-        log.info("[xc_restore] " + join(cmd))
-        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
-        child.tochild.close()
+        log.debug("[xc_restore]: %s", string.join(cmd))
 
-        lasterr = ""
-        p = select.poll()
-        p.register(child.fromchild.fileno())
-        p.register(child.childerr.fileno())
-        while True:
-            r = p.poll()
-            for (fd, event) in r:
-                if not event & select.POLLIN:
-                    continue
-                if fd == child.childerr.fileno():
-                    l = child.childerr.readline()
-                    log.error(l.rstrip())
-                    lasterr = l.rstrip()
-                if fd == child.fromchild.fileno():
-                    l = child.fromchild.readline()
-                    while l:
-                        log.info(l.rstrip())
-                        m = re.match(r"^(store-mfn) (\d+)\n$", l)
-                        if m:
-                            store_mfn = int(m.group(2))
-                            dominfo.setStoreRef(store_mfn)
-                            IntroduceDomain(dominfo.getDomid(),
-                                            store_mfn,
-                                            dominfo.store_channel.port1,
-                                            dominfo.getDomainPath())
-                        m = re.match(r"^(console-mfn) (\d+)\n$", l)
-                        if m:
-                            dominfo.setConsoleRef(int(m.group(2)))
-                        try:
-                            l = child.fromchild.readline()
-                        except:
-                            l = None
-            if filter(lambda (fd, event): event & select.POLLHUP, r):
-                break
+        def restoreInputHandler(line, _):
+            m = re.match(r"^(store-mfn) (\d+)$", line)
+            if m:
+                store_mfn = int(m.group(2))
+                dominfo.setStoreRef(store_mfn)
+                IntroduceDomain(dominfo.getDomid(),
+                                store_mfn,
+                                dominfo.store_channel.port1,
+                                dominfo.getDomainPath())
+            else:
+                m = re.match(r"^(console-mfn) (\d+)$", line)
+                if m:
+                    dominfo.setConsoleRef(int(m.group(2)))
 
-        if child.wait() >> 8 == 127:
-            lasterr = "popen %s failed" % PATH_XC_RESTORE
-        if child.wait() != 0:
-            raise XendError("xc_restore failed: %s" % lasterr)
+        forkHelper(cmd, fd, restoreInputHandler, True)
 
         return dominfo
     except:
-        log.exception("Restore failed")
         dominfo.destroy()
         raise
+
+
+def forkHelper(cmd, fd, inputHandler, closeToChild):
+    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
+
+    if closeToChild:
+        child.tochild.close()
+
+    fds = [child.fromchild.fileno(),
+           child.childerr.fileno()]
+    p = select.poll()
+    map(p.register, fds)
+    while len(fds) > 0:
+        r = p.poll()
+        for (fd, event) in r:
+            if event & select.POLLHUP or event & select.POLLERR:
+                fds.remove(fd)
+                p.unregister(fd)
+                continue
+            if not event & select.POLLIN:
+                continue
+            if fd == child.childerr.fileno():
+                lasterr = child.childerr.readline().rstrip()
+                log.error('%s', lasterr)
+            else
+                l = child.fromchild.readline().rstrip()
+                while l:
+                    log.debug('%s', l)
+                    inputHandler(l, child.tochild)
+                    try:
+                        l = child.fromchild.readline().rstrip()
+                    except:
+                        l = None
+
+    child.fromchild.close()
+    child.childerr.close()
+
+    if child.wait() >> 8 == 127:
+        lasterr = "popen failed"
+    if child.wait() != 0:
+        raise XendError("%s failed: %s" % (string.join(cmd), lasterr))

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Merge the child-process handling of the save and restore functions into one, Xen patchbot -unstable <=