ia64/xen-unstable

view tools/python/xen/xend/XendCheckpoint.py @ 6995:fdc01adc11e0

Move definition of xc, to avoid confusing pylint.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Tue Sep 20 17:25:00 2005 +0100 (2005-09-20)
parents 3133e64d0462
children 55fc0ecc19c3
line source
1 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
3 # This file is subject to the terms and conditions of the GNU General
4 # Public License. See the file "COPYING" in the main directory of
5 # this archive for more details.
7 import os
8 import re
9 import select
10 import sxp
11 from string import join
12 from struct import pack, unpack, calcsize
13 from xen.util.xpopen import xPopen3
14 import xen.lowlevel.xc
15 from xen.xend.xenstore.xsutil import IntroduceDomain
17 from XendError import XendError
18 from XendLogging import log
20 SIGNATURE = "LinuxGuestRecord"
21 PATH_XC_SAVE = "/usr/libexec/xen/xc_save"
22 PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore"
24 sizeof_int = calcsize("i")
25 sizeof_unsigned_long = calcsize("L")
28 xc = xen.lowlevel.xc.new()
31 def write_exact(fd, buf, errmsg):
32 if os.write(fd, buf) != len(buf):
33 raise XendError(errmsg)
35 def read_exact(fd, size, errmsg):
36 buf = os.read(fd, size)
37 if len(buf) != size:
38 raise XendError(errmsg)
39 return buf
41 def save(xd, fd, dominfo, live):
42 write_exact(fd, SIGNATURE, "could not write guest state file: signature")
44 config = sxp.to_string(dominfo.sxpr())
45 write_exact(fd, pack("!i", len(config)),
46 "could not write guest state file: config len")
47 write_exact(fd, config, "could not write guest state file: config")
49 # xc_save takes three customization parameters: maxit, max_f, and flags
50 # the last controls whether or not save is 'live', while the first two
51 # further customize behaviour when 'live' save is enabled. Passing "0"
52 # simply uses the defaults compiled into libxenguest; see the comments
53 # and/or code in xc_linux_save() for more information.
54 cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
55 str(dominfo.domid), "0", "0", str(int(live)) ]
56 log.info("[xc_save] " + join(cmd))
57 child = xPopen3(cmd, True, -1, [fd, xc.handle()])
59 lasterr = ""
60 p = select.poll()
61 p.register(child.fromchild.fileno())
62 p.register(child.childerr.fileno())
63 while True:
64 r = p.poll()
65 for (fd, event) in r:
66 if not event & select.POLLIN:
67 continue
68 if fd == child.childerr.fileno():
69 l = child.childerr.readline()
70 log.error(l.rstrip())
71 lasterr = l.rstrip()
72 if fd == child.fromchild.fileno():
73 l = child.fromchild.readline()
74 if l.rstrip() == "suspend":
75 log.info("suspending %d" % dominfo.domid)
76 xd.domain_shutdown(dominfo.domid, reason='suspend')
77 dominfo.state_wait("suspended")
78 log.info("suspend %d done" % dominfo.domid)
79 child.tochild.write("done\n")
80 child.tochild.flush()
81 if filter(lambda (fd, event): event & select.POLLHUP, r):
82 break
84 if child.wait() >> 8 == 127:
85 lasterr = "popen %s failed" % PATH_XC_SAVE
86 if child.wait() != 0:
87 raise XendError("xc_save failed: %s" % lasterr)
89 dominfo.closeStoreChannel()
90 xd.domain_destroy(dominfo.domid)
91 return None
93 def restore(xd, fd):
94 signature = read_exact(fd, len(SIGNATURE),
95 "not a valid guest state file: signature read")
96 if signature != SIGNATURE:
97 raise XendError("not a valid guest state file: found '%s'" %
98 signature)
100 l = read_exact(fd, sizeof_int,
101 "not a valid guest state file: config size read")
102 vmconfig_size = unpack("!i", l)[0]
103 vmconfig_buf = read_exact(fd, vmconfig_size,
104 "not a valid guest state file: config read")
106 p = sxp.Parser()
107 p.input(vmconfig_buf)
108 if not p.ready:
109 raise XendError("not a valid guest state file: config parse")
111 vmconfig = p.get_val()
112 dominfo = xd.domain_configure(vmconfig)
114 l = read_exact(fd, sizeof_unsigned_long,
115 "not a valid guest state file: pfn count read")
116 nr_pfns = unpack("=L", l)[0] # XXX endianess
117 if nr_pfns > 1024*1024: # XXX
118 raise XendError(
119 "not a valid guest state file: pfn count out of range")
121 if dominfo.store_channel:
122 store_evtchn = dominfo.store_channel.port2
123 else:
124 store_evtchn = 0
126 if dominfo.console_channel:
127 console_evtchn = dominfo.console_channel.port2
128 else:
129 console_evtchn = 0
131 cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
132 str(dominfo.domid), str(nr_pfns),
133 str(store_evtchn), str(console_evtchn)]
134 log.info("[xc_restore] " + join(cmd))
135 child = xPopen3(cmd, True, -1, [fd, xc.handle()])
136 child.tochild.close()
138 lasterr = ""
139 p = select.poll()
140 p.register(child.fromchild.fileno())
141 p.register(child.childerr.fileno())
142 while True:
143 r = p.poll()
144 for (fd, event) in r:
145 if not event & select.POLLIN:
146 continue
147 if fd == child.childerr.fileno():
148 l = child.childerr.readline()
149 log.error(l.rstrip())
150 lasterr = l.rstrip()
151 if fd == child.fromchild.fileno():
152 l = child.fromchild.readline()
153 while l:
154 log.info(l.rstrip())
155 m = re.match(r"^(store-mfn) (\d+)\n$", l)
156 if m:
157 if dominfo.store_channel:
158 dominfo.setStoreRef(int(m.group(2)))
159 if dominfo.store_mfn >= 0:
160 IntroduceDomain(dominfo.domid,
161 dominfo.store_mfn,
162 dominfo.store_channel.port1,
163 dominfo.path)
164 m = re.match(r"^(console-mfn) (\d+)\n$", l)
165 if m:
166 dominfo.setConsoleRef(int(m.group(2)))
167 try:
168 l = child.fromchild.readline()
169 except:
170 l = None
171 if filter(lambda (fd, event): event & select.POLLHUP, r):
172 break
174 if child.wait() >> 8 == 127:
175 lasterr = "popen %s failed" % PATH_XC_RESTORE
176 if child.wait() != 0:
177 raise XendError("xc_restore failed: %s" % lasterr)
179 return dominfo