else:
print "Enabled PCI access (%d:%d:%d)." % \
(pci_bus,pci_dev,pci_func)
+
+ if restore:
+ # send an unsolicited ARP reply for all non link-local IPs
+ gw=xenctl.utils.get_current_ipgw()
+ if gw == '': gw='255.255.255.255'
+ nlb=open('/proc/sys/net/ipv4/ip_nonlocal_bind','r').read()[0]=='1'
+ if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '1'
+ for ip in vfr_ipaddr:
+ if not xenctl.utils.check_subnet(ip,'169.254.0.0','255.255.0.0'):
+ print '/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw)
+ os.system('/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw))
+ if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '0'
if xc.domain_start( dom=id ) < 0:
print "Error starting domain"
u64 domid,
unsigned int sop);
+#define XCFLAGS_VERBOSE 1
+#define XCFLAGS_LIVE 2
+
int xc_linux_save(int xc_handle,
u64 domid,
- const char *state_file,
- int verbose);
+ unsigned int flags,
+ int (*writerfn)(void *, const void *, size_t),
+ void *writerst );
int xc_linux_restore(int xc_handle,
u64 domid,
- const char *state_file,
- int verbose,
+ unsigned int flags,
+ int (*readerfn)(void *, void *, size_t),
+ void *readerst,
u64 *pdomid);
int xc_linux_build(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
-static int checked_read(gzFile fd, void *buf, size_t count)
-{
- int rc;
- while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) )
- continue;
- return rc == count;
-}
int xc_linux_restore(int xc_handle,
u64 dom,
- const char *state_file,
- int verbose,
+ unsigned int flags,
+ int (*readerfn)(void *, void *, size_t),
+ void *readerst,
u64 *pdomid)
{
dom0_op_t op;
int rc = 1, i, j, n, k;
unsigned long mfn, pfn, xpfn;
unsigned int prev_pc, this_pc;
-
+ int verbose = flags & XCFLAGS_VERBOSE;
+
/* Number of page frames in use by this Linux session. */
unsigned long nr_pfns;
mfn_mapper_t *region_mapper, *mapper_handle1;
char *region_base;
- /* The name and descriptor of the file that we are reading from. */
- int fd;
- gzFile gfd;
-
mmu_t *mmu = NULL;
int pm_handle = -1;
- if ( (fd = open(state_file, O_RDONLY)) == -1 )
- {
- PERROR("Could not open state file for reading");
- return 1;
- }
-
- if ( (gfd = gzdopen(fd, "rb")) == NULL )
- {
- ERROR("Could not allocate decompression state for state file");
- close(fd);
- return 1;
- }
if ( mlock(&ctxt, sizeof(ctxt) ) )
{
}
/* Start writing out the saved-domain record. */
- if ( !checked_read(gfd, signature, 16) ||
+ if ( (*readerfn)(readerst, signature, 16) ||
(memcmp(signature, "LinuxGuestRecord", 16) != 0) )
{
ERROR("Unrecognised state format -- no signature found");
goto out;
}
- if ( !checked_read(gfd, name, sizeof(name)) ||
- !checked_read(gfd, &nr_pfns, sizeof(unsigned long)) ||
- !checked_read(gfd, &ctxt, sizeof(ctxt)) ||
- !checked_read(gfd, shared_info, PAGE_SIZE) ||
- !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
+ if ( (*readerfn)(readerst, name, sizeof(name)) ||
+ (*readerfn)(readerst, &nr_pfns, sizeof(unsigned long)) ||
+ (*readerfn)(readerst, &ctxt, sizeof(ctxt)) ||
+ (*readerfn)(readerst, shared_info, PAGE_SIZE) ||
+ (*readerfn)(readerst, pfn_to_mfn_frame_list, PAGE_SIZE) )
{
ERROR("Error when reading from state file");
goto out;
prev_pc = this_pc;
}
- if ( !checked_read(gfd, &j, sizeof(int)) )
+ if ( (*readerfn)(readerst, &j, sizeof(int)) )
{
ERROR("Error when reading from state file");
goto out;
if(j==0) break; // our work here is done
- if ( !checked_read(gfd, region_pfn_type, j*sizeof(unsigned long)) )
+ if ( (*readerfn)(readerst, region_pfn_type, j*sizeof(unsigned long)) )
{
ERROR("Error when reading from state file");
goto out;
ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
- if ( !checked_read(gfd, ppage, PAGE_SIZE) )
+ if ( (*readerfn)(readerst, ppage, PAGE_SIZE) )
{
ERROR("Error when reading from state file");
goto out;
}
- if ( region_pfn_type[i] == L1TAB )
+ switch( region_pfn_type[i] )
+ {
+ case 0:
+ break;
+
+ case L1TAB:
{
for ( k = 0; k < 1024; k++ )
{
if ( ppage[k] & _PAGE_PRESENT )
{
- if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
+ xpfn = ppage[k] >> PAGE_SHIFT;
+
+/*printf("L1 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
+ i,pfn,mfn,k,ppage[k],xpfn);*/
+
+ if ( xpfn >= nr_pfns )
{
- ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i],i,k,xpfn,nr_pfns);
+ ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns);
goto out;
}
#if 0
}
}
}
- else if ( region_pfn_type[i] == L2TAB )
+ break;
+
+ case L2TAB:
{
for ( k = 0; k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); k++ )
{
if ( ppage[k] & _PAGE_PRESENT )
{
- if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
+ xpfn = ppage[k] >> PAGE_SHIFT;
+
+/*printf("L2 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
+ i,pfn,mfn,k,ppage[k],xpfn);*/
+
+ if ( xpfn >= nr_pfns )
{
- ERROR("Frame number in page table is out of range");
+ ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns);
+
goto out;
}
#if 0
}
}
}
+ break;
+
+ default:
+ ERROR("Bogus page type %x page table is out of range. i=%d nr_pfns=%d",region_pfn_type[i],i,nr_pfns);
+ goto out;
+ }
if ( add_mmu_update(xc_handle, mmu,
(mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) )
if ( pfn_type != NULL )
free(pfn_type);
- gzclose(gfd);
if ( rc == 0 )
*pdomid = dom;
#include "xc_private.h"
#include <asm-xen/suspend.h>
-#include <zlib.h>
#define BATCH_SIZE 1024 /* 1024 pages (4MB) at a time */
})
-
-static int checked_write(gzFile fd, void *buf, size_t count)
-{
- int rc;
- while ( ((rc = gzwrite(fd, buf, count)) == -1) && (errno = EINTR) )
- continue;
- return rc == count;
-}
-
int xc_linux_save(int xc_handle,
u64 domid,
- const char *state_file,
- int verbose)
+ unsigned int flags,
+ int (*writerfn)(void *, const void *, size_t),
+ void *writerst )
{
dom0_op_t op;
int rc = 1, i, j, k, n;
unsigned long mfn;
unsigned int prev_pc, this_pc;
+ int verbose = flags & XCFLAGS_VERBOSE;
+ //int live = flags & XCFLAGS_LIVE;
/* state of the new MFN mapper */
mfn_mapper_t *mapper_handle1, *mapper_handle2;
/* A temporary mapping, and a copy, of the guest's suspend record. */
suspend_record_t *p_srec, srec;
- /* The name and descriptor of the file that we are writing to. */
- int fd;
- gzFile gfd;
-
- int pm_handle = -1;
-
- if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
- {
- PERROR("Could not open file for writing");
- return 1;
- }
-
- /*
- * Compression rate 1: we want speed over compression. We're mainly going
- * for those zero pages, after all.
- */
- if ( (gfd = gzdopen(fd, "wb1")) == NULL )
- {
- ERROR("Could not allocate compression state for state file");
- close(fd);
- return 1;
- }
if ( mlock(&ctxt, sizeof(ctxt) ) )
{
goto out;
}
- if ( !checked_write(gfd, "LinuxGuestRecord", 16) ||
- !checked_write(gfd, name, sizeof(name)) ||
- !checked_write(gfd, &srec.nr_pfns, sizeof(unsigned long)) ||
- !checked_write(gfd, &ctxt, sizeof(ctxt)) ||
- !checked_write(gfd, live_shinfo, PAGE_SIZE) ||
- !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
+ if ( (*writerfn)(writerst, "LinuxGuestRecord", 16) ||
+ (*writerfn)(writerst, name, sizeof(name)) ||
+ (*writerfn)(writerst, &srec.nr_pfns, sizeof(unsigned long)) ||
+ (*writerfn)(writerst, &ctxt, sizeof(ctxt)) ||
+ (*writerfn)(writerst, live_shinfo, PAGE_SIZE) ||
+ (*writerfn)(writerst, pfn_to_mfn_frame_list, PAGE_SIZE) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (1)");
goto out;
}
munmap(live_shinfo, PAGE_SIZE);
}
- if ( !checked_write(gfd, &j, sizeof(int) ) )
+ if ( (*writerfn)(writerst, &j, sizeof(int) ) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (2)");
goto out;
}
- if ( !checked_write(gfd, pfn_type, sizeof(unsigned long)*j ) )
+ if ( (*writerfn)(writerst, pfn_type, sizeof(unsigned long)*j ) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (3)");
goto out;
}
k++ )
{
if ( !(page[k] & _PAGE_PRESENT) ) continue;
- mfn = page[k] >> PAGE_SHIFT;
+ mfn = page[k] >> PAGE_SHIFT;
+
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
{
ERROR("Frame number in pagetable page is invalid");
page[k] &= PAGE_SIZE - 1;
page[k] |= live_mfn_to_pfn_table[mfn] << PAGE_SHIFT;
+ /*
+ printf("L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
+ pfn_type[j]>>29,
+ j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
+ */
+
}
- if ( !checked_write(gfd, page, PAGE_SIZE) )
+ if ( (*writerfn)(writerst, page, PAGE_SIZE) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (4)");
goto out;
}
}
else
{
- if ( !checked_write(gfd, region_base + (PAGE_SIZE*j), PAGE_SIZE) )
+ if ( (*writerfn)(writerst, region_base + (PAGE_SIZE*j), PAGE_SIZE) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (5)");
goto out;
}
}
rc = 0;
/* Zero terminate */
- if ( !checked_write(gfd, &rc, sizeof(int)) )
+ if ( (*writerfn)(writerst, &rc, sizeof(int)) )
{
- ERROR("Error when writing to state file");
+ ERROR("Error when writing to state file (6)");
goto out;
}
(void)do_dom0_op(xc_handle, &op);
}
- gzclose(gfd);
-
if ( pfn_type != NULL )
free(pfn_type);
-
- /* On error, make sure the file is deleted. */
- if ( rc != 0 )
- unlink(state_file);
return !!rc;
-
}
/*********************/
-#if 0
-typedef struct mfn_typer {
- domid_t dom;
- int xc_handle;
- int max;
- dom0_op_t op;
-} mfn_typer_t;
-
-
-mfn_typer_t *mfn_typer_init(int xc_handle, domid_t dom, int num );
-
-void mfn_typer_queue_entry(mfn_typer_t *t, unsigned long mfn );
-
-int mfn_typer_flush_queue(mfn_typer_t *t);
-#endif
-
-int get_pfn_type_batch(int xc_handle,
- u64 dom, int num, unsigned long *arr);
-
-unsigned int get_pfn_type(int xc_handle,
- unsigned long mfn,
- u64 dom);
-
-
#endif /* __XC_PRIVATE_H__ */
#include <Python.h>
#include <xc.h>
+#include <zlib.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
/* Needed for Python versions earlier than 2.3. */
#ifndef PyMODINIT_FUNC
u64 dom;
char *state_file;
int progress = 1;
+ unsigned int flags = 0;
static char *kwd_list[] = { "dom", "state_file", "progress", NULL };
&dom, &state_file, &progress) )
return NULL;
- if ( xc_linux_save(xc->xc_handle, dom, state_file, progress) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
- Py_INCREF(zero);
- return zero;
+ if (progress) flags |= XCFLAGS_VERBOSE;
+
+ if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0)
+ {
+#define max_namelen 64
+ char server[max_namelen];
+ char *port_s;
+ int port=777;
+ int sd = 0;
+ struct hostent *h;
+ struct sockaddr_in s;
+ int sockbufsize;
+
+ int writerfn(void *fd, const void *buf, size_t count)
+ {
+ int tot = 0, rc;
+ do
+ {
+ rc = write( (int) fd, ((char*)buf)+tot, count-tot );
+ if (rc<0) { perror("WRITE"); return rc; };
+ tot += rc;
+ }
+ while(tot<count);
+ return 0;
+ }
+
+ strncpy( server, state_file+strlen("tcp://"), max_namelen);
+ server[max_namelen-1]='\0';
+ if( port_s = strchr(server,':') )
+ {
+ *port_s = '\0';
+ port = atoi(port_s+1);
+ }
+
+ printf("X server=%s port=%d\n",server,port);
+
+ h = gethostbyname(server);
+ sd = socket (AF_INET,SOCK_STREAM,0);
+ if(sd<0) goto serr;
+ s.sin_family = AF_INET;
+ bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
+ s.sin_port = htons(port);
+ if( connect(sd, (struct sockaddr *) &s, sizeof(s)) )
+ goto serr;
+
+ sockbufsize=128*1024;
+ if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0)
+ {
+ goto serr;
+ }
+
+ if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, (void*)sd) == 0 )
+ {
+ close(sd);
+ Py_INCREF(zero);
+ return zero;
+ }
+
+ serr:
+
+ PyErr_SetFromErrno(xc_error);
+ if(sd)close(sd);
+ return NULL;
+ }
+ else
+ {
+ int fd;
+ gzFile gfd;
+
+ int writerfn(void *fd, const void *buf, size_t count)
+ {
+ int rc;
+ while ( ((rc = gzwrite( (gzFile*)fd, (void*)buf, count)) == -1) &&
+ (errno = EINTR) )
+ continue;
+ return ! (rc == count);
+ }
+
+ if (strncmp(state_file,"file:",strlen("file:")) == 0)
+ state_file += strlen("file:");
+
+ if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
+ {
+ perror("Could not open file for writing");
+ goto err;
+ }
+
+ /*
+ * Compression rate 1: we want speed over compression.
+ * We're mainly going for those zero pages, after all.
+ */
+
+ if ( (gfd = gzdopen(fd, "wb1")) == NULL )
+ {
+ perror("Could not allocate compression state for state file");
+ close(fd);
+ goto err;
+ }
+
+
+ if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, gfd) == 0 )
+ {
+ gzclose(gfd);
+ close(fd);
+
+ Py_INCREF(zero);
+ return zero;
+ }
+
+ err:
+ PyErr_SetFromErrno(xc_error);
+ if(gfd)gzclose(gfd);
+ if(fd)close(fd);
+ unlink(state_file);
+
+ return NULL;
+ }
+
}
static PyObject *pyxc_linux_restore(PyObject *self,
char *state_file;
int progress = 1;
u64 dom;
+ unsigned int flags = 0;
static char *kwd_list[] = { "dom", "state_file", "progress", NULL };
&dom, &state_file, &progress) )
return NULL;
- if ( xc_linux_restore(xc->xc_handle, dom, state_file, progress, &dom) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ if (progress) flags |= XCFLAGS_VERBOSE;
+
+ if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0)
+ {
+#define max_namelen 64
+ char server[max_namelen];
+ char *port_s;
+ int port=777;
+ int ld = 0, sd = 0;
+ struct hostent *h;
+ struct sockaddr_in s, d, p;
+ socklen_t dlen, plen;
+ int sockbufsize;
+ int on = 1;
+
+ int readerfn(void *fd, void *buf, size_t count)
+ {
+ int rc, tot = 0;
+ do {
+ rc = read( (int) fd, ((char*)buf)+tot, count-tot );
+ if (rc<0)
+ {
+ perror("READ");
+ return rc;
+ }
+ tot += rc;
+ } while( tot<count );
+
+ return 0;
+ }
+
+ strncpy( server, state_file+strlen("tcp://"), max_namelen);
+ server[max_namelen-1]='\0';
+ if( port_s = strchr(server,':') )
+ {
+ *port_s = '\0';
+ port = atoi(port_s+1);
+ }
+
+ printf("X server=%s port=%d\n",server,port);
+
+ h = gethostbyname(server);
+ ld = socket (AF_INET,SOCK_STREAM,0);
+ if(ld<0) goto serr;
+ s.sin_family = AF_INET;
+ //bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
+ s.sin_addr.s_addr = htonl(INADDR_ANY);
+ s.sin_port = htons(port);
+
+ if (setsockopt(ld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+ goto serr;
+
+ if( bind(ld, (struct sockaddr *) &s, sizeof(s)) )
+ goto serr;
+
+ if( listen(ld, 1) )
+ goto serr;
+
+ dlen=sizeof(struct sockaddr);
+ if( (sd = accept(ld, (struct sockaddr *) &d, &dlen )) < 0 )
+ goto serr;
+
+ plen = sizeof(p);
+ if (getpeername(sd, (struct sockaddr_in *) &p,
+ &plen) < 0) {
+ goto serr;
+ }
+
+ printf("Accepted connection from %s\n",
+ inet_ntoa(p.sin_addr));
+
+ sockbufsize=128*1024;
+ if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0)
+ {
+ goto serr;
+ }
+
+ if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, (void*)sd, &dom) == 0 )
+ {
+ close(sd);
+ Py_INCREF(zero);
+ return zero;
+ }
+
+ serr:
+
+ PyErr_SetFromErrno(xc_error);
+ if(ld)close(ld);
+ if(sd)close(sd);
+ return NULL;
+ }
+ else
+ {
+ int fd;
+ gzFile gfd;
+
+ int readerfn(void *fd, void *buf, size_t count)
+ {
+ int rc;
+ while ( ((rc = gzread( (gzFile*)fd, (void*)buf, count)) == -1) &&
+ (errno = EINTR) )
+ continue;
+ return ! (rc == count);
+ }
+
+ if (strncmp(state_file,"file:",strlen("file:")) == 0)
+ state_file += strlen("file:");
+
+ if ( (fd = open(state_file, O_RDONLY)) == -1 )
+ {
+ perror("Could not open file for writing");
+ goto err;
+ }
+
+ /*
+ * Compression rate 1: we want speed over compression.
+ * We're mainly going for those zero pages, after all.
+ */
+
+ if ( (gfd = gzdopen(fd, "rb")) == NULL )
+ {
+ perror("Could not allocate compression state for state file");
+ close(fd);
+ goto err;
+ }
+
+
+ if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, gfd, &dom) == 0 )
+ {
+ gzclose(gfd);
+ close(fd);
+
+ Py_INCREF(zero);
+ return zero;
+ }
+
+ err:
+ PyErr_SetFromErrno(xc_error);
+ if(gfd)gzclose(gfd);
+ if(fd)close(fd);
+ return NULL;
+ }
- Py_INCREF(zero);
- return zero;
}
static PyObject *pyxc_linux_build(PyObject *self,
#
source drivers/input/Config.in
else
+ define_bool CONFIG_NETDEVICES y
+
#
# Block device driver configuration
#