bitkeeper revision 1.1488.1.1 (428e39badumj52vi-nzb7GBmoVe2dA)

XendDomainInfo.py, XendDomain.py, xc.c, xc_linux_restore.c, xc.h:
  Implement the parts of vm restore which need interaction with xend
  as part of xend, instead of using xfrd.  The restore functionality
  using xfrd was broken anyway since xend didn't handle the callback
  channel from xfrd correctly.
xen_domain.c:
  Disable restore in xfrd.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-05-20 19:25:46 +00:00
1 parent 19a92cce63
commit 3277f00e2a
6 files changed
+187 -233

No files matched your search

+19 -39
View File
@@ -334,62 +334,41 @@ static PyObject *pyxc_linux_save(PyObject *self,
return val;
}
static int file_restore(XcObject *xc, XcIOContext *ioctxt, char *state_file)
{
int rc = -1;
ioctxt->io = gzip_stream_fopen(state_file, "rb");
if ( ioctxt->io == NULL )
{
xcio_perror(ioctxt, "Could not open file for reading");
return rc;
}
rc = xc_linux_restore(xc->xc_handle, ioctxt);
IOStream_close(ioctxt->io);
return rc;
}
static PyObject *pyxc_linux_restore(PyObject *self,
PyObject *args,
PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
char *state_file;
int progress = 1, debug = 0;
PyObject *val = NULL;
XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
int rc =-1;
int io_fd, dom;
unsigned long nr_pfns;
char *pfn2mfn;
int pfn2mfn_len;
PyObject *pfn2mfn_object;
static char *kwd_list[] = { "state_file", "progress", "debug", NULL };
static char *kwd_list[] = { "fd", "dom", "pfns", "pfn2mfn", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s|ii", kwd_list,
&state_file,
&progress,
&debug) )
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iilO", kwd_list,
&io_fd, &dom, &nr_pfns,
&pfn2mfn_object) )
goto exit;
if ( progress )
ioctxt.flags |= XCFLAGS_VERBOSE;
if ( debug )
ioctxt.flags |= XCFLAGS_DEBUG;
if (PyString_AsStringAndSize(pfn2mfn_object, &pfn2mfn, &pfn2mfn_len))
goto exit;
if ( (state_file == NULL) || (state_file[0] == '\0') )
goto exit;
if (pfn2mfn_len != PAGE_SIZE)
goto exit;
rc = file_restore(xc, &ioctxt, state_file);
rc = xc_linux_restore(xc->xc_handle, io_fd, dom, nr_pfns, pfn2mfn);
if ( rc != 0 )
{
PyErr_SetFromErrno(xc_error);
goto exit;
}
val = Py_BuildValue("{s:i,s:s}",
"dom", ioctxt.domain,
"vmconfig", ioctxt.vmconfig);
Py_INCREF(zero);
val = zero;
exit:
return val;
@@ -1061,8 +1040,9 @@ static PyMethodDef pyxc_methods[] = {
(PyCFunction)pyxc_linux_restore,
METH_VARARGS | METH_KEYWORDS, "\n"
"Restore the CPU and memory state of a Linux guest OS.\n"
" state_file [str]: Name of state file. Must not currently exist.\n"
" progress [int, 1]: Bool - display a running progress indication?\n\n"
" dom [int]: Identifier of domain to be restored.\n"
" pfns [int]: Number of pages domain uses.\n"
" pfn2mfn [str]: String containing the pfn to mfn frame list.\n\n"
"Returns: [int] new domain identifier on success; -1 on error.\n" },
{ "linux_build",
+64 -7
View File
@@ -24,6 +24,9 @@ import scheduler
from xen.xend.server import channel
import errno
from struct import pack, unpack, calcsize
__all__ = [ "XendDomain" ]
SHUTDOWN_TIMEOUT = 30
@@ -298,7 +301,7 @@ class XendDomain:
[dominfo.name, dominfo.id, "fail"])
return dominfo
def domain_configure(self, id, vmconfig):
def domain_configure(self, vmconfig):
"""Configure an existing domain. This is intended for internal
use by domain restore and migrate.
@@ -306,10 +309,7 @@ class XendDomain:
@param vmconfig: vm configuration
"""
config = sxp.child_value(vmconfig, 'config')
dominfo = self.domain_lookup(id)
log.debug('domain_configure> id=%s config=%s', str(id), str(config))
if dominfo.config:
raise XendError("Domain already configured: " + dominfo.id)
dominfo = XendDomainInfo.tmp_restore_create_domain()
dominfo.dom_construct(dominfo.dom, config)
self._add_domain(dominfo)
return dominfo
@@ -320,8 +320,65 @@ class XendDomain:
@param src: source file
@param progress: output progress if true
"""
xmigrate = XendMigrate.instance()
return xmigrate.restore_begin(src)
SIGNATURE = "LinuxGuestRecord"
sizeof_int = calcsize("L")
sizeof_unsigned_long = calcsize("i")
PAGE_SIZE = 4096
class XendFile(file):
def read_exact(self, size, error_msg):
buf = self.read(size)
if len(buf) != size:
raise XendError(error_msg)
return buf
try:
fd = XendFile(src, 'rb')
signature = fd.read_exact(len(SIGNATURE),
"not a valid guest state file: signature read")
if signature != SIGNATURE:
raise XendError("not a valid guest state file: found '%s'" %
signature)
l = fd.read_exact(sizeof_unsigned_long,
"not a valid guest state file: pfn count read")
nr_pfns = unpack("=L", l)[0] # XXX endianess
if nr_pfns > 1024*1024: # XXX
raise XendError(
"not a valid guest state file: pfn count out of range")
pfn_to_mfn_frame_list = fd.read_exact(PAGE_SIZE,
"not a valid guest state file: pfn_to_mfn_frame_list read")
l = fd.read_exact(sizeof_int,
"not a valid guest state file: config size read")
vmconfig_size = unpack("i", l)[0] # XXX endianess
vmconfig_buf = fd.read_exact(vmconfig_size,
"not a valid guest state file: config read")
p = sxp.Parser()
p.input(vmconfig_buf)
if not p.ready:
raise XendError("not a valid guest state file: config parse")
vmconfig = p.get_val()
dominfo = self.domain_configure(vmconfig)
# XXXcl hack: fd.tell will sync up the object and
# underlying file descriptor
ignore = fd.tell()
xc.linux_restore(fd.fileno(), int(dominfo.id), nr_pfns,
pfn_to_mfn_frame_list)
return dominfo
except IOError, ex:
if ex.errno == errno.ENOENT:
raise XendError("can't open guest state file %s" % src)
else:
raise
def domain_get(self, id):
"""Get up-to-date info about a domain.
+7
View File
@@ -183,6 +183,13 @@ def vm_create(config):
vm.construct(config)
return vm
def tmp_restore_create_domain():
# dom input parameter is ignored
vm = XendDomainInfo()
dom = xc.domain_create()
vm.setdom(dom)
return vm
def vm_recreate(savedinfo, info):
"""Create the VM object for an existing domain.
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.