bitkeeper revision 1.1491 (428e39d2dbOTFoU5SeRaUuYmn0Q84w)

Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into firebug.cl.cam.ac.uk:/local/scratch/cl349/xen-unstable.bk
This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-05-20 19:26:10 +00:00
commit 9a00a27ea4
6 files changed
+187 -233

No files matched your search

+2 -1
View File
@@ -244,7 +244,8 @@ int xc_linux_save(int xc_handle, struct XcIOContext *ioctxt);
* @parm ioctxt the IO context to restore a domain from
* @return 0 on success, -1 on failure
*/
int xc_linux_restore(int xc_handle, struct XcIOContext *ioctxt);
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
unsigned char *pfn2mfn);
int xc_linux_build(int xc_handle,
u32 domid,
+93 -186
View File
@@ -13,59 +13,34 @@
#define DEBUG 0
#if 1
#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
#else
#define ERR(_f, _a...) ((void)0)
#endif
#if DEBUG
#define DPRINTF(_f, _a...) printf ( _f , ## _a )
#define DPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
#else
#define DPRINTF(_f, _a...) ((void)0)
#endif
/** Read the vmconfig string from the state input.
* It is stored as a 4-byte count 'n' followed by n bytes.
* The config data is stored in a new string in 'ioctxt->vmconfig',
* and is null-terminated. The count is stored in 'ioctxt->vmconfig_n'.
*
* @param ioctxt i/o context
* @return 0 on success, non-zero on error.
*/
static int read_vmconfig(XcIOContext *ioctxt)
{
int err = -1;
#define PROGRESS 0
#if PROGRESS
#define PPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
#else
#define PPRINTF(_f, _a...)
#endif
if ( xcio_read(ioctxt, &ioctxt->vmconfig_n, sizeof(ioctxt->vmconfig_n)) )
goto exit;
ioctxt->vmconfig = malloc(ioctxt->vmconfig_n + 1);
if ( ioctxt->vmconfig == NULL )
goto exit;
if ( xcio_read(ioctxt, ioctxt->vmconfig, ioctxt->vmconfig_n) )
goto exit;
ioctxt->vmconfig[ioctxt->vmconfig_n] = '\0';
err = 0;
exit:
if ( err )
{
if ( ioctxt->vmconfig != NULL )
free(ioctxt->vmconfig);
ioctxt->vmconfig = NULL;
ioctxt->vmconfig_n = 0;
}
return err;
}
int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
unsigned char *pfn2mfn)
{
dom0_op_t op;
int rc = 1, i, n, k;
unsigned long mfn, pfn, xpfn;
unsigned int prev_pc, this_pc;
u32 dom = 0;
int verify = 0;
/* Number of page frames in use by this Linux session. */
unsigned long nr_pfns;
int verify = 0;
int err;
/* The new domain's shared-info frame number. */
unsigned long shared_info_frame;
@@ -75,9 +50,6 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
/* A copy of the CPU context of the guest. */
vcpu_guest_context_t ctxt;
/* First 16 bytes of the state file must contain 'LinuxGuestRecord'. */
char signature[16];
/* A table containg the type of each PFN (/not/ MFN!). */
unsigned long *pfn_type = NULL;
@@ -88,7 +60,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
unsigned long *ppage = NULL;
/* A copy of the pfn-to-mfn table frame list. */
unsigned long pfn_to_mfn_frame_list[1024];
unsigned long *pfn_to_mfn_frame_list = (void *)pfn2mfn; // [1024];
/* A table mapping each PFN to its new MFN. */
unsigned long *pfn_to_mfn_table = NULL;
@@ -110,126 +82,68 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
struct mmuext_op pin[MAX_PIN_BATCH];
unsigned int nr_pins = 0;
xcio_info(ioctxt, "xc_linux_restore start\n");
DPRINTF("xc_linux_restore start\n");
if ( mlock(&ctxt, sizeof(ctxt) ) )
{
if (mlock(&ctxt, sizeof(ctxt))) {
/* needed for when we do the build dom0 op,
but might as well do early */
PERROR("Unable to mlock ctxt");
ERR("Unable to mlock ctxt");
return 1;
}
/* Start reading the saved-domain record. */
if ( xcio_read(ioctxt, signature, 16) ||
(memcmp(signature, "LinuxGuestRecord", 16) != 0) )
{
xcio_error(ioctxt, "Unrecognised state format -- no signature found");
goto out;
}
if ( xcio_read(ioctxt, &nr_pfns, sizeof(unsigned long)) ||
xcio_read(ioctxt, pfn_to_mfn_frame_list, PAGE_SIZE) )
{
xcio_error(ioctxt, "Error reading header");
goto out;
}
if ( read_vmconfig(ioctxt) )
{
xcio_error(ioctxt, "Error writing vmconfig");
goto out;
}
if ( nr_pfns > 1024*1024 )
{
xcio_error(ioctxt, "Invalid state file -- pfn count out of range");
goto out;
}
/* We want zeroed memory so use calloc rather than malloc. */
pfn_to_mfn_table = calloc(1, 4 * nr_pfns);
pfn_type = calloc(1, 4 * nr_pfns);
region_mfn = calloc(1, 4 * MAX_BATCH_SIZE);
pfn_to_mfn_table = calloc(4, nr_pfns);
pfn_type = calloc(4, nr_pfns);
region_mfn = calloc(4, MAX_BATCH_SIZE);
if ( (pfn_to_mfn_table == NULL) ||
(pfn_type == NULL) ||
(region_mfn == NULL) )
{
if ((pfn_to_mfn_table == NULL) || (pfn_type == NULL) ||
(region_mfn == NULL)) {
ERR("memory alloc failed");
errno = ENOMEM;
goto out;
}
if ( mlock(region_mfn, 4 * MAX_BATCH_SIZE ) )
{
xcio_error(ioctxt, "Could not mlock region_mfn");
if (mlock(region_mfn, 4 * MAX_BATCH_SIZE)) {
ERR("Could not mlock region_mfn");
goto out;
}
/* Create domain on CPU -1 so that it may auto load-balance in future. */
if ( xc_domain_create(xc_handle, &dom) )
{
xcio_error(ioctxt, "Could not create domain.");
goto out;
}
if ( xc_domain_setcpuweight(xc_handle, dom, 1) )
{
xcio_error(ioctxt, "Could not set domain cpuweight.");
goto out;
}
if ( xc_domain_setmaxmem(xc_handle, dom, nr_pfns * (PAGE_SIZE / 1024)) )
{
xcio_error(ioctxt, "Could not set domain maxmem. pfns=%ld, %ldKB",
nr_pfns, nr_pfns * (PAGE_SIZE / 1024));
goto out;
}
if ( xc_domain_memory_increase_reservation(xc_handle, dom,
nr_pfns * (PAGE_SIZE / 1024)) )
{
xcio_error(ioctxt,
"Could not increase domain memory reservation. pfns=%ld",
nr_pfns);
goto out;
}
ioctxt->domain = dom;
xcio_info(ioctxt, "Created domain %u\n", dom);
/* Get the domain's shared-info frame. */
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = (domid_t)dom;
if ( do_dom0_op(xc_handle, &op) < 0 )
{
xcio_error(ioctxt, "Could not get information on new domain");
if (do_dom0_op(xc_handle, &op) < 0) {
ERR("Could not get information on new domain");
goto out;
}
shared_info_frame = op.u.getdomaininfo.shared_info_frame;
if(ioctxt->flags & XCFLAGS_CONFIGURE)
{
if(xcio_configure_domain(ioctxt))
{
xcio_error(ioctxt, "Configuring domain failed");
goto out;
}
err = xc_domain_setmaxmem(xc_handle, dom, nr_pfns * PAGE_SIZE / 1024);
if (err != 0) {
errno = ENOMEM;
goto out;
}
err = xc_domain_memory_increase_reservation(xc_handle, dom,
nr_pfns * PAGE_SIZE / 1024);
if (err != 0) {
errno = ENOMEM;
goto out;
}
/* Build the pfn-to-mfn table. We choose MFN ordering returned by Xen. */
if ( xc_get_pfn_list(xc_handle, dom,
pfn_to_mfn_table, nr_pfns) != nr_pfns )
{
xcio_error(ioctxt, "Did not read correct number of frame "
"numbers for new dom");
if (xc_get_pfn_list(xc_handle, dom, pfn_to_mfn_table, nr_pfns) !=
nr_pfns) {
ERR("Did not read correct number of frame numbers for new dom");
goto out;
}
if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
{
xcio_error(ioctxt, "Could not initialise for MMU updates");
mmu = init_mmu_updates(xc_handle, dom);
if (mmu == NULL) {
ERR("Could not initialise for MMU updates");
goto out;
}
xcio_info(ioctxt, "Reloading memory pages: 0%%");
DPRINTF("Reloading memory pages: 0%%");
/*
* Now simply read each saved frame into its new machine frame.
@@ -246,17 +160,17 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
this_pc = (n * 100) / nr_pfns;
if ( (this_pc - prev_pc) >= 5 )
{
xcio_info(ioctxt, "\b\b\b\b%3d%%", this_pc);
PPRINTF("\b\b\b\b%3d%%", this_pc);
prev_pc = this_pc;
}
if ( xcio_read(ioctxt, &j, sizeof(int)) )
if ( read(io_fd, &j, sizeof(int)) != sizeof(int) )
{
xcio_error(ioctxt, "Error when reading from state file");
ERR("Error when reading from state file");
goto out;
}
DPRINTF("batch %d\n",j);
PPRINTF("batch %d\n",j);
if ( j == -1 )
{
@@ -270,12 +184,13 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
if ( j > MAX_BATCH_SIZE )
{
xcio_error(ioctxt, "Max batch size exceeded. Giving up.");
ERR("Max batch size exceeded. Giving up.");
goto out;
}
if ( xcio_read(ioctxt, region_pfn_type, j*sizeof(unsigned long)) ) {
xcio_error(ioctxt, "Error when reading from state file");
if ( read(io_fd, region_pfn_type, j*sizeof(unsigned long)) !=
j*sizeof(unsigned long) ) {
ERR("Error when reading from state file");
goto out;
}
@@ -297,7 +212,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
region_mfn,
j )) == 0 )
{
xcio_error(ioctxt, "map batch failed");
ERR("map batch failed");
goto out;
}
@@ -311,7 +226,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
if (pfn>nr_pfns)
{
xcio_error(ioctxt, "pfn out of range");
ERR("pfn out of range");
goto out;
}
@@ -326,9 +241,9 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
else
ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
if ( xcio_read(ioctxt, ppage, PAGE_SIZE) )
if ( read(io_fd, ppage, PAGE_SIZE) != PAGE_SIZE )
{
xcio_error(ioctxt, "Error when reading from state file");
ERR("Error when reading from state file");
goto out;
}
@@ -346,7 +261,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
xpfn = ppage[k] >> PAGE_SHIFT;
if ( xpfn >= nr_pfns )
{
xcio_error(ioctxt, "Frame number in type %lu page "
ERR("Frame number in type %lu page "
"table is out of range. i=%d k=%d "
"pfn=0x%lx nr_pfns=%lu",
region_pfn_type[i]>>28, i,
@@ -374,7 +289,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
if ( xpfn >= nr_pfns )
{
xcio_error(ioctxt, "Frame number in type %lu page"
ERR("Frame number in type %lu page"
" table is out of range. i=%d k=%d "
"pfn=%lu nr_pfns=%lu",
region_pfn_type[i]>>28, i, k,
@@ -391,7 +306,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
break;
default:
xcio_error(ioctxt, "Bogus page type %lx page table is "
ERR("Bogus page type %lx page table is "
"out of range. i=%d nr_pfns=%lu",
region_pfn_type[i], i, nr_pfns);
goto out;
@@ -432,7 +347,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
n+=j; /* crude stats */
}
xcio_info(ioctxt, "Received all pages\n");
DPRINTF("Received all pages\n");
if ( finish_mmu_updates(xc_handle, mmu) )
goto out;
@@ -462,30 +377,31 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
(do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
goto out;
xcio_info(ioctxt, "\b\b\b\b100%%\n");
xcio_info(ioctxt, "Memory reloaded.\n");
DPRINTF("\b\b\b\b100%%\n");
DPRINTF("Memory reloaded.\n");
/* Get the list of PFNs that are not in the psuedo-phys map */
{
unsigned int count, *pfntab;
int rc;
if ( xcio_read(ioctxt, &count, sizeof(count)) )
if ( read(io_fd, &count, sizeof(count)) != sizeof(count) )
{
xcio_error(ioctxt, "Error when reading from state file");
ERR("Error when reading from state file");
goto out;
}
pfntab = malloc( sizeof(unsigned int) * count );
if ( pfntab == NULL )
{
xcio_error(ioctxt, "Out of memory");
ERR("Out of memory");
goto out;
}
if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) )
if ( read(io_fd, pfntab, sizeof(unsigned int)*count) !=
sizeof(unsigned int)*count )
{
xcio_error(ioctxt, "Error when reading pfntab from state file");
ERR("Error when reading pfntab from state file");
goto out;
}
@@ -502,7 +418,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
MEMOP_decrease_reservation,
pfntab, count, 0, dom )) <0 )
{
xcio_error(ioctxt, "Could not decrease reservation : %d",rc);
ERR("Could not decrease reservation : %d",rc);
goto out;
}
else
@@ -512,10 +428,10 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
}
}
if ( xcio_read(ioctxt, &ctxt, sizeof(ctxt)) ||
xcio_read(ioctxt, shared_info_page, PAGE_SIZE) )
if ( read(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
read(io_fd, shared_info_page, PAGE_SIZE) != PAGE_SIZE )
{
xcio_error(ioctxt, "Error when reading from state file");
ERR("Error when reading from state file");
goto out;
}
@@ -523,7 +439,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
pfn = ctxt.user_regs.esi;
if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
{
xcio_error(ioctxt, "Suspend record frame number is bad");
ERR("Suspend record frame number is bad");
goto out;
}
ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
@@ -537,7 +453,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
/* Uncanonicalise each GDT frame number. */
if ( ctxt.gdt_ents > 8192 )
{
xcio_error(ioctxt, "GDT entry count out of range");
ERR("GDT entry count out of range");
goto out;
}
@@ -546,7 +462,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
pfn = ctxt.gdt_frames[i];
if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
{
xcio_error(ioctxt, "GDT frame number is bad");
ERR("GDT frame number is bad");
goto out;
}
ctxt.gdt_frames[i] = pfn_to_mfn_table[pfn];
@@ -558,7 +474,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
{
printf("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx\n",
pfn, nr_pfns, pfn_type[pfn], (unsigned long)L2TAB);
xcio_error(ioctxt, "PT base is bad.");
ERR("PT base is bad.");
goto out;
}
ctxt.pt_base = pfn_to_mfn_table[pfn] << PAGE_SHIFT;
@@ -583,7 +499,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
pfn = pfn_to_mfn_frame_list[i];
if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
{
xcio_error(ioctxt, "PFN-to-MFN frame number is bad");
ERR("PFN-to-MFN frame number is bad");
goto out;
}
mfn = pfn_to_mfn_table[pfn];
@@ -596,7 +512,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
pfn_to_mfn_frame_list,
(nr_pfns+1023)/1024 )) == 0 )
{
xcio_error(ioctxt, "Couldn't map pfn_to_mfn table");
ERR("Couldn't map pfn_to_mfn table");
goto out;
}
@@ -636,11 +552,11 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
(ctxt.ldt_base > HYPERVISOR_VIRT_START) ||
((ctxt.ldt_base + ctxt.ldt_ents*8) > HYPERVISOR_VIRT_START) )
{
xcio_error(ioctxt, "Bad LDT base or size");
ERR("Bad LDT base or size");
goto out;
}
xcio_info(ioctxt, "Domain ready to be built.\n");
DPRINTF("Domain ready to be built.\n");
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = (domid_t)dom;
@@ -650,26 +566,20 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
if ( rc != 0 )
{
xcio_error(ioctxt, "Couldn't build the domain");
ERR("Couldn't build the domain");
goto out;
}
if ( ioctxt->flags & XCFLAGS_CONFIGURE )
{
xcio_info(ioctxt, "Domain ready to be unpaused\n");
op.cmd = DOM0_UNPAUSEDOMAIN;
op.u.unpausedomain.domain = (domid_t)dom;
rc = do_dom0_op(xc_handle, &op);
}
if ( rc == 0 )
{
DPRINTF("Domain ready to be unpaused\n");
op.cmd = DOM0_UNPAUSEDOMAIN;
op.u.unpausedomain.domain = (domid_t)dom;
rc = do_dom0_op(xc_handle, &op);
if (rc == 0) {
/* Success: print the domain id. */
xcio_info(ioctxt, "DOM=%u\n", dom);
DPRINTF("DOM=%u\n", dom);
return 0;
}
out:
if ( (rc != 0) && (dom != 0) )
xc_domain_destroy(xc_handle, dom);
@@ -680,9 +590,6 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
if ( pfn_type != NULL )
free(pfn_type);
if ( rc == 0 )
ioctxt->domain = dom;
DPRINTF("Restore exit with rc=%d\n",rc);
DPRINTF("Restore exit with rc=%d\n", rc);
return rc;
}
+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.
+2
View File
@@ -87,6 +87,7 @@ int xen_domain_rcv(IOStream *io,
char **vmconfig, int *vmconfig_n,
int *configured){
int err = 0;
#if 0
XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
dprintf(">\n");
ioctxt->io = io;
@@ -102,6 +103,7 @@ int xen_domain_rcv(IOStream *io,
*vmconfig_n = ioctxt->vmconfig_n;
*configured = (ioctxt->flags & XCFLAGS_CONFIGURE);
dprintf("< err=%d\n", err);
#endif
return err;
}
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.