|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC Patch v2 12/16] XendCheckpoint: implement colo
In colo mode, XendCheckpoit.py will communicate with both master and
xc_restore. This patch implements this communication. In colo mode,
the signature is "GuestColoRestore".
Signed-off-by: Ye Wei <wei.ye1987@xxxxxxxxx>
Signed-off-by: Jiang Yunhong <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx>
---
tools/python/xen/xend/XendCheckpoint.py | 127 +++++++++++++++++++++---------
1 files changed, 89 insertions(+), 38 deletions(-)
diff --git a/tools/python/xen/xend/XendCheckpoint.py
b/tools/python/xen/xend/XendCheckpoint.py
index fa09757..ed71690 100644
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -23,8 +23,11 @@ from xen.xend.XendLogging import log
from xen.xend.XendConfig import XendConfig
from xen.xend.XendConstants import *
from xen.xend import XendNode
+from xen.xend.xenstore.xsutil import ResumeDomain
+from xen.remus import util
SIGNATURE = "LinuxGuestRecord"
+COLO_SIGNATURE = "GuestColoRestore"
QEMU_SIGNATURE = "QemuDeviceModelRecord"
dm_batch = 512
XC_SAVE = "xc_save"
@@ -203,10 +206,15 @@ def restore(xd, fd, dominfo = None, paused = False,
relocating = False):
signature = read_exact(fd, len(SIGNATURE),
"not a valid guest state file: signature read")
- if signature != SIGNATURE:
+ if signature != SIGNATURE and signature != COLO_SIGNATURE:
raise XendError("not a valid guest state file: found '%s'" %
signature)
+ if signature == COLO_SIGNATURE:
+ colo = True
+ else:
+ colo = False
+
l = read_exact(fd, sizeof_int,
"not a valid guest state file: config size read")
vmconfig_size = unpack("!i", l)[0]
@@ -301,12 +309,15 @@ def restore(xd, fd, dominfo = None, paused = False,
relocating = False):
cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
fd, dominfo.getDomid(),
- store_port, console_port, int(is_hvm), pae, apic,
superpages])
+ store_port, console_port, int(is_hvm), pae, apic,
+ superpages, int(colo)])
log.debug("[xc_restore]: %s", string.join(cmd))
- handler = RestoreInputHandler()
+ inputHandler = RestoreInputHandler()
+ restoreHandler = RestoreHandler(fd, colo, dominfo, inputHandler,
+ restore_image)
- forkHelper(cmd, fd, handler.handler, True)
+ forkHelper(cmd, fd, inputHandler.handler, not colo, restoreHandler)
# We don't want to pass this fd to any other children -- we
# might need to recover the disk space that backs it.
@@ -321,42 +332,74 @@ def restore(xd, fd, dominfo = None, paused = False,
relocating = False):
raise XendError('Could not read store MFN')
if not is_hvm and handler.console_mfn is None:
- raise XendError('Could not read console MFN')
+ raise XendError('Could not read console MFN')
+
+ restoreHandler.resume(True, paused, None)
+
+ return dominfo
+ except Exception, exn:
+ dominfo.destroy()
+ log.exception(exn)
+ raise exn
+
+
+class RestoreHandler:
+ def __init__(self, fd, colo, dominfo, inputHandler, restore_image):
+ self.fd = fd
+ self.colo = colo
+ self.firsttime = True
+ self.inputHandler = inputHandler
+ self.dominfo = dominfo
+ self.restore_image = restore_image
+ self.store_port = dominfo.store_port
+ self.console_port = dominfo.console_port
+
+ def resume(self, finish, paused, child):
+ fd = self.fd
+ dominfo = self.dominfo
+ handler = self.inputHandler
+ restore_image = self.restore_image
restore_image.setCpuid()
+ dominfo.completeRestore(handler.store_mfn, handler.console_mfn,
+ self.firsttime)
- # xc_restore will wait for source to close connection
-
- dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
+ if self.colo and not finish:
+ # notify master that checkpoint finishes
+ write_exact(fd, "finish", "failed to write finish done")
+ buf = read_exact(fd, 6, "failed to read resume flag")
+ if buf != "resume":
+ return False
- #
- # We shouldn't hold the domains_lock over a waitForDevices
- # As this function sometime gets called holding this lock,
- # we must release it and re-acquire it appropriately
- #
from xen.xend import XendDomain
- lock = True;
- try:
- XendDomain.instance().domains_lock.release()
- except:
- lock = False;
-
- try:
- dominfo.waitForDevices() # Wait for backends to set up
- finally:
- if lock:
- XendDomain.instance().domains_lock.acquire()
+ if self.firsttime:
+ lock = True
+ try:
+ XendDomain.instance().domains_lock.release()
+ except:
+ lock = False
+
+ try:
+ dominfo.waitForDevices() # Wait for backends to set up
+ finally:
+ if lock:
+ XendDomain.instance().domains_lock.acquire()
+ if not paused:
+ dominfo.unpause()
+ else:
+ # colo
+ xc.domain_resume(dominfo.domid, 0)
+ ResumeDomain(dominfo.domid)
- if not paused:
- dominfo.unpause()
+ if self.colo and not finish:
+ child.tochild.write("resume")
+ child.tochild.flush()
- return dominfo
- except Exception, exn:
- dominfo.destroy()
- log.exception(exn)
- raise exn
+ dominfo.store_port = self.store_port
+ dominfo.console_port = self.console_port
+ self.firsttime = False
class RestoreInputHandler:
def __init__(self):
@@ -364,17 +407,25 @@ class RestoreInputHandler:
self.console_mfn = None
- def handler(self, line, _):
+ def handler(self, line, child, restoreHandler):
+ if line == "finish":
+ # colo
+ return restoreHandler.resume(False, False, child)
+
m = re.match(r"^(store-mfn) (\d+)$", line)
if m:
self.store_mfn = int(m.group(2))
- else:
- m = re.match(r"^(console-mfn) (\d+)$", line)
- if m:
- self.console_mfn = int(m.group(2))
+ return True
+
+ m = re.match(r"^(console-mfn) (\d+)$", line)
+ if m:
+ self.console_mfn = int(m.group(2))
+ return True
+
+ return False
-def forkHelper(cmd, fd, inputHandler, closeToChild):
+def forkHelper(cmd, fd, inputHandler, closeToChild, restoreHandler):
child = xPopen3(cmd, True, -1, [fd])
if closeToChild:
@@ -392,7 +443,7 @@ def forkHelper(cmd, fd, inputHandler, closeToChild):
else:
line = line.rstrip()
log.debug('%s', line)
- inputHandler(line, child.tochild)
+ inputHandler(line, child, restoreHandler)
except IOError, exn:
raise XendError('Error reading from child process for %s: %s' %
--
1.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |