ia64/xen-unstable

changeset 1342:8b4e4b30b2bb

bitkeeper revision 1.886.1.1 (4097c3c1KkMumw6Mz5K7HxRBJXhY3Q)

suspend/resume migration improvements
author iap10@labyrinth.cl.cam.ac.uk
date Tue May 04 16:24:33 2004 +0000 (2004-05-04)
parents 343bab45b371
children edc18ca91c16
files tools/examples/xc_dom_create.py tools/xc/lib/xc.h tools/xc/lib/xc_linux_restore.c tools/xc/lib/xc_linux_save.c tools/xc/lib/xc_private.h tools/xc/py/Xc.c xenolinux-2.4.26-sparse/arch/xen/config.in
line diff
     1.1 --- a/tools/examples/xc_dom_create.py	Mon May 03 21:36:57 2004 +0000
     1.2 +++ b/tools/examples/xc_dom_create.py	Tue May 04 16:24:33 2004 +0000
     1.3 @@ -351,6 +351,18 @@ def make_domain():
     1.4              else:
     1.5                  print "Enabled PCI access (%d:%d:%d)." % \
     1.6                        (pci_bus,pci_dev,pci_func)
     1.7 +		
     1.8 +    if restore:
     1.9 +	# send an unsolicited ARP reply for all non link-local IPs
    1.10 +	gw=xenctl.utils.get_current_ipgw()
    1.11 +	if gw == '': gw='255.255.255.255'
    1.12 +	nlb=open('/proc/sys/net/ipv4/ip_nonlocal_bind','r').read()[0]=='1'
    1.13 +	if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '1'
    1.14 +	for ip in vfr_ipaddr:
    1.15 +	    if not xenctl.utils.check_subnet(ip,'169.254.0.0','255.255.0.0'):
    1.16 +		print     '/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw)
    1.17 +		os.system('/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw))
    1.18 +	if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '0'
    1.19  
    1.20      if xc.domain_start( dom=id ) < 0:
    1.21          print "Error starting domain"
     2.1 --- a/tools/xc/lib/xc.h	Mon May 03 21:36:57 2004 +0000
     2.2 +++ b/tools/xc/lib/xc.h	Tue May 04 16:24:33 2004 +0000
     2.3 @@ -58,15 +58,20 @@ int xc_shadow_control(int xc_handle,
     2.4                        u64 domid, 
     2.5                        unsigned int sop);
     2.6  
     2.7 +#define XCFLAGS_VERBOSE 1
     2.8 +#define XCFLAGS_LIVE    2
     2.9 +
    2.10  int xc_linux_save(int xc_handle,
    2.11                    u64 domid, 
    2.12 -                  const char *state_file, 
    2.13 -                  int verbose);
    2.14 +                  unsigned int flags,
    2.15 +		  int (*writerfn)(void *, const void *, size_t),
    2.16 +		  void *writerst );
    2.17  
    2.18  int xc_linux_restore(int xc_handle,
    2.19                       u64 domid,
    2.20 -                     const char *state_file, 
    2.21 -                     int verbose,
    2.22 +                     unsigned int flags,		     
    2.23 +		     int (*readerfn)(void *, void *, size_t),
    2.24 +		     void *readerst,
    2.25                       u64 *pdomid);
    2.26  
    2.27  int xc_linux_build(int xc_handle,
     3.1 --- a/tools/xc/lib/xc_linux_restore.c	Mon May 03 21:36:57 2004 +0000
     3.2 +++ b/tools/xc/lib/xc_linux_restore.c	Tue May 04 16:24:33 2004 +0000
     3.3 @@ -45,25 +45,20 @@ static int get_pfn_list(int xc_handle,
     3.4      return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
     3.5  }
     3.6  
     3.7 -static int checked_read(gzFile fd, void *buf, size_t count)
     3.8 -{
     3.9 -    int rc;
    3.10 -    while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) )
    3.11 -        continue;
    3.12 -    return rc == count;
    3.13 -}
    3.14  
    3.15  int xc_linux_restore(int xc_handle,
    3.16  		     u64 dom,
    3.17 -                     const char *state_file,
    3.18 -                     int verbose,
    3.19 +                     unsigned int flags,
    3.20 +		     int (*readerfn)(void *, void *, size_t),
    3.21 +		     void *readerst,
    3.22                       u64 *pdomid)
    3.23  {
    3.24      dom0_op_t op;
    3.25      int rc = 1, i, j, n, k;
    3.26      unsigned long mfn, pfn, xpfn;
    3.27      unsigned int prev_pc, this_pc;
    3.28 -    
    3.29 +    int verbose = flags & XCFLAGS_VERBOSE;
    3.30 +
    3.31      /* Number of page frames in use by this Linux session. */
    3.32      unsigned long nr_pfns;
    3.33  
    3.34 @@ -98,26 +93,10 @@ int xc_linux_restore(int xc_handle,
    3.35      mfn_mapper_t *region_mapper, *mapper_handle1;
    3.36      char *region_base;
    3.37  
    3.38 -    /* The name and descriptor of the file that we are reading from. */
    3.39 -    int    fd;
    3.40 -    gzFile gfd;
    3.41 -
    3.42      mmu_t *mmu = NULL;
    3.43  
    3.44      int pm_handle = -1;
    3.45  
    3.46 -    if ( (fd = open(state_file, O_RDONLY)) == -1 )
    3.47 -    {
    3.48 -        PERROR("Could not open state file for reading");
    3.49 -        return 1;
    3.50 -    }
    3.51 -
    3.52 -    if ( (gfd = gzdopen(fd, "rb")) == NULL )
    3.53 -    {
    3.54 -        ERROR("Could not allocate decompression state for state file");
    3.55 -        close(fd);
    3.56 -        return 1;
    3.57 -    }
    3.58  
    3.59      if ( mlock(&ctxt, sizeof(ctxt) ) )
    3.60      {   
    3.61 @@ -128,18 +107,18 @@ int xc_linux_restore(int xc_handle,
    3.62      }
    3.63  
    3.64      /* Start writing out the saved-domain record. */
    3.65 -    if ( !checked_read(gfd, signature, 16) ||
    3.66 +    if ( (*readerfn)(readerst, signature, 16) ||
    3.67           (memcmp(signature, "LinuxGuestRecord", 16) != 0) )
    3.68      {
    3.69          ERROR("Unrecognised state format -- no signature found");
    3.70          goto out;
    3.71      }
    3.72  
    3.73 -    if ( !checked_read(gfd, name,                  sizeof(name)) ||
    3.74 -         !checked_read(gfd, &nr_pfns,              sizeof(unsigned long)) ||
    3.75 -         !checked_read(gfd, &ctxt,                 sizeof(ctxt)) ||
    3.76 -         !checked_read(gfd, shared_info,           PAGE_SIZE) ||
    3.77 -         !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
    3.78 +    if ( (*readerfn)(readerst, name,                  sizeof(name)) ||
    3.79 +         (*readerfn)(readerst, &nr_pfns,              sizeof(unsigned long)) ||
    3.80 +         (*readerfn)(readerst, &ctxt,                 sizeof(ctxt)) ||
    3.81 +         (*readerfn)(readerst, shared_info,           PAGE_SIZE) ||
    3.82 +         (*readerfn)(readerst, pfn_to_mfn_frame_list, PAGE_SIZE) )
    3.83      {
    3.84          ERROR("Error when reading from state file");
    3.85          goto out;
    3.86 @@ -250,7 +229,7 @@ int xc_linux_restore(int xc_handle,
    3.87              prev_pc = this_pc;
    3.88          }
    3.89  
    3.90 -        if ( !checked_read(gfd, &j, sizeof(int)) )
    3.91 +        if ( (*readerfn)(readerst, &j, sizeof(int)) )
    3.92          {
    3.93              ERROR("Error when reading from state file");
    3.94              goto out;
    3.95 @@ -260,7 +239,7 @@ int xc_linux_restore(int xc_handle,
    3.96  	
    3.97  	if(j==0) break;  // our work here is done
    3.98  	
    3.99 -        if ( !checked_read(gfd, region_pfn_type, j*sizeof(unsigned long)) )
   3.100 +        if ( (*readerfn)(readerst, region_pfn_type, j*sizeof(unsigned long)) )
   3.101          {
   3.102              ERROR("Error when reading from state file");
   3.103              goto out;
   3.104 @@ -306,21 +285,31 @@ int xc_linux_restore(int xc_handle,
   3.105  
   3.106              ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
   3.107  
   3.108 -	    if ( !checked_read(gfd, ppage, PAGE_SIZE) )
   3.109 +	    if ( (*readerfn)(readerst, ppage, PAGE_SIZE) )
   3.110  	    {
   3.111  		ERROR("Error when reading from state file");
   3.112  		goto out;
   3.113  	    }
   3.114  
   3.115 -	    if ( region_pfn_type[i] == L1TAB )
   3.116 +	    switch( region_pfn_type[i] )
   3.117 +	    {
   3.118 +	    case 0:
   3.119 +		break;
   3.120 +
   3.121 +	    case L1TAB:
   3.122  	    {
   3.123  		for ( k = 0; k < 1024; k++ )
   3.124  		{
   3.125  		    if ( ppage[k] & _PAGE_PRESENT )
   3.126  		    {
   3.127 -			if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
   3.128 +			xpfn = ppage[k] >> PAGE_SHIFT;
   3.129 +
   3.130 +/*printf("L1 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
   3.131 +       i,pfn,mfn,k,ppage[k],xpfn);*/
   3.132 +
   3.133 +			if ( xpfn >= nr_pfns )
   3.134  			{
   3.135 -			    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);
   3.136 +			    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);
   3.137  			    goto out;
   3.138  			}
   3.139  #if 0
   3.140 @@ -335,15 +324,23 @@ int xc_linux_restore(int xc_handle,
   3.141  		    }
   3.142  		}
   3.143  	    }
   3.144 -	    else if ( region_pfn_type[i] == L2TAB )
   3.145 +	    break;
   3.146 +
   3.147 +	    case L2TAB:
   3.148  	    {
   3.149  		for ( k = 0; k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); k++ )
   3.150  		{
   3.151  		    if ( ppage[k] & _PAGE_PRESENT )
   3.152  		    {
   3.153 -			if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
   3.154 +			xpfn = ppage[k] >> PAGE_SHIFT;
   3.155 +
   3.156 +/*printf("L2 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
   3.157 +       i,pfn,mfn,k,ppage[k],xpfn);*/
   3.158 +
   3.159 +			if ( xpfn >= nr_pfns )
   3.160  			{
   3.161 -			    ERROR("Frame number in page table is out of range");
   3.162 +			    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);
   3.163 +
   3.164  			    goto out;
   3.165  			}
   3.166  #if 0
   3.167 @@ -358,6 +355,12 @@ int xc_linux_restore(int xc_handle,
   3.168  		    }
   3.169  		}
   3.170  	    }
   3.171 +	    break;
   3.172 +
   3.173 +	    default:
   3.174 +		ERROR("Bogus page type %x page table is out of range. i=%d nr_pfns=%d",region_pfn_type[i],i,nr_pfns);
   3.175 +		goto out;
   3.176 +	    }
   3.177  
   3.178  	    if ( add_mmu_update(xc_handle, mmu,
   3.179  				(mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) )
   3.180 @@ -545,7 +548,6 @@ int xc_linux_restore(int xc_handle,
   3.181      if ( pfn_type != NULL )
   3.182          free(pfn_type);
   3.183  
   3.184 -    gzclose(gfd);
   3.185  
   3.186      if ( rc == 0 )
   3.187          *pdomid = dom;
     4.1 --- a/tools/xc/lib/xc_linux_save.c	Mon May 03 21:36:57 2004 +0000
     4.2 +++ b/tools/xc/lib/xc_linux_save.c	Tue May 04 16:24:33 2004 +0000
     4.3 @@ -8,7 +8,6 @@
     4.4  
     4.5  #include "xc_private.h"
     4.6  #include <asm-xen/suspend.h>
     4.7 -#include <zlib.h>
     4.8  
     4.9  #define BATCH_SIZE 1024   /* 1024 pages (4MB) at a time */
    4.10  
    4.11 @@ -41,24 +40,18 @@
    4.12  })
    4.13  
    4.14  
    4.15 -
    4.16 -static int checked_write(gzFile fd, void *buf, size_t count)
    4.17 -{
    4.18 -    int rc;
    4.19 -    while ( ((rc = gzwrite(fd, buf, count)) == -1) && (errno = EINTR) )
    4.20 -        continue;
    4.21 -    return rc == count;
    4.22 -}
    4.23 -
    4.24  int xc_linux_save(int xc_handle,
    4.25                    u64 domid, 
    4.26 -                  const char *state_file, 
    4.27 -                  int verbose)
    4.28 +		  unsigned int flags,
    4.29 +		  int (*writerfn)(void *, const void *, size_t),
    4.30 +		  void *writerst )
    4.31  {
    4.32      dom0_op_t op;
    4.33      int rc = 1, i, j, k, n;
    4.34      unsigned long mfn;
    4.35      unsigned int prev_pc, this_pc;
    4.36 +    int verbose = flags & XCFLAGS_VERBOSE;
    4.37 +    //int live = flags & XCFLAGS_LIVE;
    4.38  
    4.39      /* state of the new MFN mapper */
    4.40      mfn_mapper_t *mapper_handle1, *mapper_handle2;
    4.41 @@ -99,28 +92,6 @@ int xc_linux_save(int xc_handle,
    4.42      /* A temporary mapping, and a copy, of the guest's suspend record. */
    4.43      suspend_record_t *p_srec, srec;
    4.44  
    4.45 -    /* The name and descriptor of the file that we are writing to. */
    4.46 -    int    fd;
    4.47 -    gzFile gfd;
    4.48 -
    4.49 -    int pm_handle = -1;
    4.50 -
    4.51 -    if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
    4.52 -    {
    4.53 -        PERROR("Could not open file for writing");
    4.54 -        return 1;
    4.55 -    }
    4.56 -
    4.57 -    /*
    4.58 -     * Compression rate 1: we want speed over compression. We're mainly going
    4.59 -     * for those zero pages, after all.
    4.60 -     */
    4.61 -    if ( (gfd = gzdopen(fd, "wb1")) == NULL )
    4.62 -    {
    4.63 -        ERROR("Could not allocate compression state for state file");
    4.64 -        close(fd);
    4.65 -        return 1;
    4.66 -    }
    4.67  
    4.68      if ( mlock(&ctxt, sizeof(ctxt) ) )
    4.69      {
    4.70 @@ -324,14 +295,14 @@ int xc_linux_save(int xc_handle,
    4.71          goto out;
    4.72      }
    4.73  
    4.74 -    if ( !checked_write(gfd, "LinuxGuestRecord",    16) ||
    4.75 -         !checked_write(gfd, name,                  sizeof(name)) ||
    4.76 -         !checked_write(gfd, &srec.nr_pfns,         sizeof(unsigned long)) ||
    4.77 -         !checked_write(gfd, &ctxt,                 sizeof(ctxt)) ||
    4.78 -         !checked_write(gfd, live_shinfo,           PAGE_SIZE) ||
    4.79 -         !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
    4.80 +    if ( (*writerfn)(writerst, "LinuxGuestRecord",    16) ||
    4.81 +         (*writerfn)(writerst, name,                  sizeof(name)) ||
    4.82 +         (*writerfn)(writerst, &srec.nr_pfns,         sizeof(unsigned long)) ||
    4.83 +         (*writerfn)(writerst, &ctxt,                 sizeof(ctxt)) ||
    4.84 +         (*writerfn)(writerst, live_shinfo,           PAGE_SIZE) ||
    4.85 +         (*writerfn)(writerst, pfn_to_mfn_frame_list, PAGE_SIZE) )
    4.86      {
    4.87 -        ERROR("Error when writing to state file");
    4.88 +        ERROR("Error when writing to state file (1)");
    4.89          goto out;
    4.90      }
    4.91      munmap(live_shinfo, PAGE_SIZE);
    4.92 @@ -401,15 +372,15 @@ int xc_linux_save(int xc_handle,
    4.93  	}
    4.94  
    4.95  
    4.96 -	if ( !checked_write(gfd, &j, sizeof(int) ) )
    4.97 +	if ( (*writerfn)(writerst, &j, sizeof(int) ) )
    4.98  	{
    4.99 -	    ERROR("Error when writing to state file");
   4.100 +	    ERROR("Error when writing to state file (2)");
   4.101  	    goto out;
   4.102  	}
   4.103  
   4.104 -	if ( !checked_write(gfd, pfn_type, sizeof(unsigned long)*j ) )
   4.105 +	if ( (*writerfn)(writerst, pfn_type, sizeof(unsigned long)*j ) )
   4.106  	{
   4.107 -	    ERROR("Error when writing to state file");
   4.108 +	    ERROR("Error when writing to state file (3)");
   4.109  	    goto out;
   4.110  	}
   4.111  
   4.112 @@ -430,7 +401,8 @@ int xc_linux_save(int xc_handle,
   4.113  		      k++ )
   4.114  		{
   4.115  		    if ( !(page[k] & _PAGE_PRESENT) ) continue;
   4.116 -		    mfn = page[k] >> PAGE_SHIFT;
   4.117 +		    mfn = page[k] >> PAGE_SHIFT;		    
   4.118 +
   4.119  		    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
   4.120  		    {
   4.121  			ERROR("Frame number in pagetable page is invalid");
   4.122 @@ -439,11 +411,17 @@ int xc_linux_save(int xc_handle,
   4.123  		    page[k] &= PAGE_SIZE - 1;
   4.124   		    page[k] |= live_mfn_to_pfn_table[mfn] << PAGE_SHIFT;
   4.125  
   4.126 +		    /*
   4.127 +		    printf("L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
   4.128 +			   pfn_type[j]>>29,
   4.129 +			   j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
   4.130 +			   */
   4.131 +
   4.132  		}
   4.133  
   4.134 -		if ( !checked_write(gfd, page, PAGE_SIZE) )
   4.135 +		if ( (*writerfn)(writerst, page, PAGE_SIZE) )
   4.136  		{
   4.137 -		    ERROR("Error when writing to state file");
   4.138 +		    ERROR("Error when writing to state file (4)");
   4.139  		    goto out;
   4.140  		}
   4.141  
   4.142 @@ -451,9 +429,9 @@ int xc_linux_save(int xc_handle,
   4.143  	    }
   4.144  	    else
   4.145  	    {
   4.146 -		if ( !checked_write(gfd, region_base + (PAGE_SIZE*j), PAGE_SIZE) )
   4.147 +		if ( (*writerfn)(writerst, region_base + (PAGE_SIZE*j), PAGE_SIZE) )
   4.148  		{
   4.149 -		    ERROR("Error when writing to state file");
   4.150 +		    ERROR("Error when writing to state file (5)");
   4.151  		    goto out;
   4.152  		}
   4.153  	    }
   4.154 @@ -468,9 +446,9 @@ int xc_linux_save(int xc_handle,
   4.155      rc = 0;
   4.156  
   4.157      /* Zero terminate */
   4.158 -    if ( !checked_write(gfd, &rc, sizeof(int)) )
   4.159 +    if ( (*writerfn)(writerst, &rc, sizeof(int)) )
   4.160      {
   4.161 -	ERROR("Error when writing to state file");
   4.162 +	ERROR("Error when writing to state file (6)");
   4.163  	goto out;
   4.164      }
   4.165      
   4.166 @@ -485,16 +463,9 @@ out:
   4.167          (void)do_dom0_op(xc_handle, &op);
   4.168      }
   4.169  
   4.170 -    gzclose(gfd);
   4.171 -
   4.172      if ( pfn_type != NULL )
   4.173          free(pfn_type);
   4.174 -
   4.175 -    /* On error, make sure the file is deleted. */
   4.176 -    if ( rc != 0 )
   4.177 -        unlink(state_file);
   4.178      
   4.179      return !!rc;
   4.180  
   4.181 -
   4.182  }
     5.1 --- a/tools/xc/lib/xc_private.h	Mon May 03 21:36:57 2004 +0000
     5.2 +++ b/tools/xc/lib/xc_private.h	Tue May 04 16:24:33 2004 +0000
     5.3 @@ -246,28 +246,4 @@ void * mfn_mapper_queue_entry(mfn_mapper
     5.4  /*********************/
     5.5  
     5.6  
     5.7 -#if 0
     5.8 -typedef struct mfn_typer {
     5.9 -    domid_t dom;
    5.10 -    int xc_handle;
    5.11 -    int max;
    5.12 -    dom0_op_t op;
    5.13 -} mfn_typer_t;
    5.14 -
    5.15 -
    5.16 -mfn_typer_t *mfn_typer_init(int xc_handle, domid_t dom, int num );
    5.17 -
    5.18 -void mfn_typer_queue_entry(mfn_typer_t *t, unsigned long mfn );
    5.19 -
    5.20 -int mfn_typer_flush_queue(mfn_typer_t *t);
    5.21 -#endif
    5.22 -
    5.23 -int get_pfn_type_batch(int xc_handle, 
    5.24 -		       u64 dom, int num, unsigned long *arr);
    5.25 -
    5.26 -unsigned int get_pfn_type(int xc_handle, 
    5.27 -			  unsigned long mfn, 
    5.28 -			  u64 dom);
    5.29 -    
    5.30 -
    5.31  #endif /* __XC_PRIVATE_H__ */
     6.1 --- a/tools/xc/py/Xc.c	Mon May 03 21:36:57 2004 +0000
     6.2 +++ b/tools/xc/py/Xc.c	Tue May 04 16:24:33 2004 +0000
     6.3 @@ -6,6 +6,13 @@
     6.4  
     6.5  #include <Python.h>
     6.6  #include <xc.h>
     6.7 +#include <zlib.h>
     6.8 +#include <fcntl.h>
     6.9 +#include <netinet/in.h>
    6.10 +#include <netinet/tcp.h>
    6.11 +#include <sys/types.h>
    6.12 +#include <sys/socket.h>
    6.13 +#include <netdb.h>
    6.14  
    6.15  /* Needed for Python versions earlier than 2.3. */
    6.16  #ifndef PyMODINIT_FUNC
    6.17 @@ -183,6 +190,7 @@ static PyObject *pyxc_linux_save(PyObjec
    6.18      u64   dom;
    6.19      char *state_file;
    6.20      int   progress = 1;
    6.21 +    unsigned int flags = 0;
    6.22  
    6.23      static char *kwd_list[] = { "dom", "state_file", "progress", NULL };
    6.24  
    6.25 @@ -190,11 +198,124 @@ static PyObject *pyxc_linux_save(PyObjec
    6.26                                        &dom, &state_file, &progress) )
    6.27          return NULL;
    6.28  
    6.29 -    if ( xc_linux_save(xc->xc_handle, dom, state_file, progress) != 0 )
    6.30 -        return PyErr_SetFromErrno(xc_error);
    6.31 -    
    6.32 -    Py_INCREF(zero);
    6.33 -    return zero;
    6.34 +    if (progress) flags |= XCFLAGS_VERBOSE;
    6.35 +
    6.36 +    if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0)
    6.37 +    {
    6.38 +#define max_namelen 64
    6.39 +	char server[max_namelen];
    6.40 +	char *port_s;
    6.41 +	int port=777;
    6.42 +	int sd = 0;
    6.43 +	struct hostent *h;
    6.44 +	struct sockaddr_in s;
    6.45 +	int sockbufsize;
    6.46 +
    6.47 +	int writerfn(void *fd, const void *buf, size_t count)
    6.48 +	{
    6.49 +	    int tot = 0, rc;
    6.50 +	    do 
    6.51 +	    {
    6.52 +		rc = write( (int) fd, ((char*)buf)+tot, count-tot );
    6.53 +		if (rc<0) { perror("WRITE"); return rc; };
    6.54 +		tot += rc;
    6.55 +	    }
    6.56 +	    while(tot<count);
    6.57 +	    return 0;
    6.58 +	}
    6.59 +
    6.60 +	strncpy( server, state_file+strlen("tcp://"), max_namelen);
    6.61 +	server[max_namelen-1]='\0';
    6.62 +	if( port_s = strchr(server,':') )
    6.63 +	{
    6.64 +	    *port_s = '\0';
    6.65 +	    port = atoi(port_s+1);
    6.66 +	}
    6.67 +
    6.68 +	printf("X server=%s port=%d\n",server,port);
    6.69 +	
    6.70 +	h = gethostbyname(server);
    6.71 +	sd = socket (AF_INET,SOCK_STREAM,0);
    6.72 +	if(sd<0) goto serr;
    6.73 +	s.sin_family = AF_INET;
    6.74 +	bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
    6.75 +	s.sin_port = htons(port);
    6.76 +	if( connect(sd, (struct sockaddr *) &s, sizeof(s)) ) 
    6.77 +	    goto serr;
    6.78 +
    6.79 +	sockbufsize=128*1024;
    6.80 +	if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0) 
    6.81 +	{
    6.82 +	    goto serr;
    6.83 +	}
    6.84 +
    6.85 +	if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, (void*)sd) == 0 )
    6.86 +	{
    6.87 +	    close(sd);
    6.88 +	    Py_INCREF(zero);
    6.89 +	    return zero;
    6.90 +	}
    6.91 +
    6.92 +	serr:
    6.93 +
    6.94 +	PyErr_SetFromErrno(xc_error);
    6.95 +	if(sd)close(sd);
    6.96 +	return NULL;
    6.97 +    }    
    6.98 +    else
    6.99 +    {
   6.100 +	int fd;
   6.101 +	gzFile gfd;
   6.102 +
   6.103 +	int writerfn(void *fd, const void *buf, size_t count)
   6.104 +	{
   6.105 +	    int rc;
   6.106 +	    while ( ((rc = gzwrite( (gzFile*)fd, (void*)buf, count)) == -1) && 
   6.107 +		    (errno = EINTR) )
   6.108 +		continue;
   6.109 +	    return ! (rc == count);
   6.110 +	}
   6.111 +
   6.112 +	if (strncmp(state_file,"file:",strlen("file:")) == 0)
   6.113 +	    state_file += strlen("file:");
   6.114 +
   6.115 +	if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
   6.116 +	{
   6.117 +	    perror("Could not open file for writing");
   6.118 +	    goto err;
   6.119 +	}
   6.120 +
   6.121 +	/*
   6.122 +	 * Compression rate 1: we want speed over compression. 
   6.123 +	 * We're mainly going for those zero pages, after all.
   6.124 +	 */
   6.125 +
   6.126 +	if ( (gfd = gzdopen(fd, "wb1")) == NULL )
   6.127 +	{
   6.128 +	    perror("Could not allocate compression state for state file");
   6.129 +	    close(fd);
   6.130 +	    goto err;
   6.131 +	}
   6.132 +
   6.133 +
   6.134 +	if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, gfd) == 0 )
   6.135 +	{
   6.136 +	    gzclose(gfd);
   6.137 +	    close(fd);
   6.138 +
   6.139 +	    Py_INCREF(zero);
   6.140 +	    return zero;
   6.141 +	}
   6.142 +
   6.143 +    err:
   6.144 +	PyErr_SetFromErrno(xc_error);
   6.145 +	if(gfd)gzclose(gfd);
   6.146 +	if(fd)close(fd);
   6.147 +	unlink(state_file);
   6.148 +
   6.149 +	return NULL;
   6.150 +    }
   6.151 +
   6.152  }
   6.153  
   6.154  static PyObject *pyxc_linux_restore(PyObject *self,
   6.155 @@ -206,6 +327,7 @@ static PyObject *pyxc_linux_restore(PyOb
   6.156      char        *state_file;
   6.157      int          progress = 1;
   6.158      u64          dom;
   6.159 +    unsigned int flags = 0;
   6.160  
   6.161      static char *kwd_list[] = { "dom", "state_file", "progress", NULL };
   6.162  
   6.163 @@ -213,11 +335,149 @@ static PyObject *pyxc_linux_restore(PyOb
   6.164                                        &dom, &state_file, &progress) )
   6.165          return NULL;
   6.166  
   6.167 -    if ( xc_linux_restore(xc->xc_handle, dom, state_file, progress, &dom) != 0 )
   6.168 -        return PyErr_SetFromErrno(xc_error);
   6.169 +    if (progress) flags |= XCFLAGS_VERBOSE;
   6.170 +
   6.171 +    if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0)
   6.172 +    {
   6.173 +#define max_namelen 64
   6.174 +	char server[max_namelen];
   6.175 +	char *port_s;
   6.176 +	int port=777;
   6.177 +	int ld = 0, sd = 0;
   6.178 +	struct hostent *h;
   6.179 +	struct sockaddr_in s, d, p;
   6.180 +	socklen_t dlen, plen;
   6.181 +	int sockbufsize;
   6.182 +	int on = 1;
   6.183 +
   6.184 +	int readerfn(void *fd, void *buf, size_t count)
   6.185 +	{
   6.186 +	    int rc, tot = 0;
   6.187 +	    do { 
   6.188 +		rc = read( (int) fd, ((char*)buf)+tot, count-tot ); 
   6.189 +		if (rc<0)
   6.190 +		    {
   6.191 +			perror("READ");
   6.192 +			return rc;
   6.193 +		    }
   6.194 +		tot += rc;
   6.195 +	    } while( tot<count );
   6.196 +
   6.197 +	    return 0;
   6.198 +	}
   6.199 +
   6.200 +	strncpy( server, state_file+strlen("tcp://"), max_namelen);
   6.201 +	server[max_namelen-1]='\0';
   6.202 +	if( port_s = strchr(server,':') )
   6.203 +	{
   6.204 +	    *port_s = '\0';
   6.205 +	    port = atoi(port_s+1);
   6.206 +	}
   6.207 +
   6.208 +	printf("X server=%s port=%d\n",server,port);
   6.209 +	
   6.210 +	h = gethostbyname(server);
   6.211 +	ld = socket (AF_INET,SOCK_STREAM,0);
   6.212 +	if(ld<0) goto serr;
   6.213 +	s.sin_family = AF_INET;
   6.214 +	//bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
   6.215 +	s.sin_addr.s_addr = htonl(INADDR_ANY);
   6.216 +	s.sin_port = htons(port);
   6.217 +
   6.218 +	if (setsockopt(ld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
   6.219 +	    goto serr;
   6.220 +
   6.221 +	if( bind(ld, (struct sockaddr *) &s, sizeof(s)) ) 
   6.222 +	    goto serr;
   6.223 +
   6.224 +	if( listen(ld, 1) )
   6.225 +	    goto serr;
   6.226 +
   6.227 +	dlen=sizeof(struct sockaddr);
   6.228 +	if( (sd = accept(ld, (struct sockaddr *) &d, &dlen )) < 0 )
   6.229 +	    goto serr;
   6.230 +
   6.231 +        plen = sizeof(p);
   6.232 +	if (getpeername(sd, (struct sockaddr_in *) &p, 
   6.233 +			&plen) < 0) {
   6.234 +	    goto serr;
   6.235 +	}
   6.236  
   6.237 -    Py_INCREF(zero);
   6.238 -    return zero;
   6.239 +	printf("Accepted connection from %s\n",
   6.240 +			inet_ntoa(p.sin_addr));
   6.241 +	
   6.242 +	sockbufsize=128*1024;
   6.243 +	if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0) 
   6.244 +	{
   6.245 +	    goto serr;
   6.246 +	}
   6.247 +
   6.248 +	if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, (void*)sd, &dom) == 0 )
   6.249 +	{
   6.250 +	    close(sd);
   6.251 +	    Py_INCREF(zero);
   6.252 +	    return zero;
   6.253 +	}
   6.254 +
   6.255 +	serr:
   6.256 +
   6.257 +	PyErr_SetFromErrno(xc_error);
   6.258 +	if(ld)close(ld);
   6.259 +	if(sd)close(sd);
   6.260 +	return NULL;
   6.261 +    }    
   6.262 +    else
   6.263 +    {
   6.264 +	int fd;
   6.265 +	gzFile gfd;
   6.266 +
   6.267 +	int readerfn(void *fd, void *buf, size_t count)
   6.268 +	{
   6.269 +	    int rc;
   6.270 +	    while ( ((rc = gzread( (gzFile*)fd, (void*)buf, count)) == -1) && 
   6.271 +		    (errno = EINTR) )
   6.272 +		continue;
   6.273 +	    return ! (rc == count);
   6.274 +	}
   6.275 +
   6.276 +	if (strncmp(state_file,"file:",strlen("file:")) == 0)
   6.277 +	    state_file += strlen("file:");
   6.278 +
   6.279 +	if ( (fd = open(state_file, O_RDONLY)) == -1 )
   6.280 +	{
   6.281 +	    perror("Could not open file for writing");
   6.282 +	    goto err;
   6.283 +	}
   6.284 +
   6.285 +	/*
   6.286 +	 * Compression rate 1: we want speed over compression. 
   6.287 +	 * We're mainly going for those zero pages, after all.
   6.288 +	 */
   6.289 +
   6.290 +	if ( (gfd = gzdopen(fd, "rb")) == NULL )
   6.291 +	{
   6.292 +	    perror("Could not allocate compression state for state file");
   6.293 +	    close(fd);
   6.294 +	    goto err;
   6.295 +	}
   6.296 +
   6.297 +
   6.298 +	if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, gfd, &dom) == 0 )
   6.299 +	{
   6.300 +	    gzclose(gfd);
   6.301 +	    close(fd);
   6.302 +
   6.303 +	    Py_INCREF(zero);
   6.304 +	    return zero;
   6.305 +	}
   6.306 +
   6.307 +    err:
   6.308 +	PyErr_SetFromErrno(xc_error);
   6.309 +	if(gfd)gzclose(gfd);
   6.310 +	if(fd)close(fd);
   6.311 +	return NULL;
   6.312 +    }
   6.313 +
   6.314  }
   6.315  
   6.316  static PyObject *pyxc_linux_build(PyObject *self,
     7.1 --- a/xenolinux-2.4.26-sparse/arch/xen/config.in	Mon May 03 21:36:57 2004 +0000
     7.2 +++ b/xenolinux-2.4.26-sparse/arch/xen/config.in	Tue May 04 16:24:33 2004 +0000
     7.3 @@ -231,6 +231,8 @@ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" 
     7.4     #
     7.5     source drivers/input/Config.in
     7.6  else
     7.7 +   define_bool CONFIG_NETDEVICES y
     7.8 +
     7.9     #
    7.10     # Block device driver configuration
    7.11     #