ia64/xen-unstable

changeset 5053:fb7d59789e4d

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>
author cl349@firebug.cl.cam.ac.uk
date Fri May 20 19:25:46 2005 +0000 (2005-05-20)
parents 636f2a45038f
children 95c16a18cc65
files tools/libxc/xc.h tools/libxc/xc_linux_restore.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/xfrd/xen_domain.c
line diff
     1.1 --- a/tools/libxc/xc.h	Fri May 20 15:23:48 2005 +0000
     1.2 +++ b/tools/libxc/xc.h	Fri May 20 19:25:46 2005 +0000
     1.3 @@ -244,7 +244,8 @@ int xc_linux_save(int xc_handle, struct 
     1.4   * @parm ioctxt the IO context to restore a domain from
     1.5   * @return 0 on success, -1 on failure
     1.6   */
     1.7 -int xc_linux_restore(int xc_handle, struct XcIOContext *ioctxt);
     1.8 +int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
     1.9 +		     unsigned char *pfn2mfn);
    1.10  
    1.11  int xc_linux_build(int xc_handle,
    1.12                     u32 domid,
     2.1 --- a/tools/libxc/xc_linux_restore.c	Fri May 20 15:23:48 2005 +0000
     2.2 +++ b/tools/libxc/xc_linux_restore.c	Fri May 20 19:25:46 2005 +0000
     2.3 @@ -13,59 +13,34 @@
     2.4  
     2.5  #define DEBUG 0
     2.6  
     2.7 +#if 1
     2.8 +#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
     2.9 +#else
    2.10 +#define ERR(_f, _a...) ((void)0)
    2.11 +#endif
    2.12 +
    2.13  #if DEBUG
    2.14 -#define DPRINTF(_f, _a...) printf ( _f , ## _a )
    2.15 +#define DPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
    2.16  #else
    2.17  #define DPRINTF(_f, _a...) ((void)0)
    2.18  #endif
    2.19  
    2.20 -/** Read the vmconfig string from the state input.
    2.21 - * It is stored as a 4-byte count 'n' followed by n bytes.
    2.22 - * The config data is stored in a new string in 'ioctxt->vmconfig',
    2.23 - * and is null-terminated. The count is stored in 'ioctxt->vmconfig_n'.
    2.24 - *
    2.25 - * @param ioctxt i/o context
    2.26 - * @return 0 on success, non-zero on error.
    2.27 - */
    2.28 -static int read_vmconfig(XcIOContext *ioctxt)
    2.29 -{
    2.30 -    int err = -1;
    2.31 -
    2.32 -    if ( xcio_read(ioctxt, &ioctxt->vmconfig_n, sizeof(ioctxt->vmconfig_n)) )
    2.33 -        goto exit;
    2.34 -
    2.35 -    ioctxt->vmconfig = malloc(ioctxt->vmconfig_n + 1);
    2.36 -    if ( ioctxt->vmconfig == NULL ) 
    2.37 -        goto exit;
    2.38 +#define PROGRESS 0
    2.39 +#if PROGRESS
    2.40 +#define PPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
    2.41 +#else
    2.42 +#define PPRINTF(_f, _a...)
    2.43 +#endif
    2.44  
    2.45 -    if ( xcio_read(ioctxt, ioctxt->vmconfig, ioctxt->vmconfig_n) )
    2.46 -        goto exit;
    2.47 -
    2.48 -    ioctxt->vmconfig[ioctxt->vmconfig_n] = '\0';
    2.49 -    err = 0;
    2.50 -
    2.51 -  exit:
    2.52 -    if ( err )
    2.53 -    {
    2.54 -        if ( ioctxt->vmconfig != NULL )
    2.55 -            free(ioctxt->vmconfig);
    2.56 -        ioctxt->vmconfig = NULL;
    2.57 -        ioctxt->vmconfig_n = 0;
    2.58 -    }
    2.59 -    return err;
    2.60 -}
    2.61 -
    2.62 -int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
    2.63 +int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
    2.64 +                     unsigned char *pfn2mfn)
    2.65  {
    2.66      dom0_op_t op;
    2.67      int rc = 1, i, n, k;
    2.68      unsigned long mfn, pfn, xpfn;
    2.69      unsigned int prev_pc, this_pc;
    2.70 -    u32 dom = 0;
    2.71 -    int verify = 0; 
    2.72 -
    2.73 -    /* Number of page frames in use by this Linux session. */
    2.74 -    unsigned long nr_pfns;
    2.75 +    int verify = 0;
    2.76 +    int err;
    2.77  
    2.78      /* The new domain's shared-info frame number. */
    2.79      unsigned long shared_info_frame;
    2.80 @@ -75,9 +50,6 @@ int xc_linux_restore(int xc_handle, XcIO
    2.81      /* A copy of the CPU context of the guest. */
    2.82      vcpu_guest_context_t ctxt;
    2.83  
    2.84 -    /* First 16 bytes of the state file must contain 'LinuxGuestRecord'. */
    2.85 -    char signature[16];
    2.86 -    
    2.87      /* A table containg the type of each PFN (/not/ MFN!). */
    2.88      unsigned long *pfn_type = NULL;
    2.89  
    2.90 @@ -88,7 +60,7 @@ int xc_linux_restore(int xc_handle, XcIO
    2.91      unsigned long *ppage = NULL;
    2.92  
    2.93      /* A copy of the pfn-to-mfn table frame list. */
    2.94 -    unsigned long pfn_to_mfn_frame_list[1024];
    2.95 +    unsigned long *pfn_to_mfn_frame_list = (void *)pfn2mfn; // [1024];
    2.96  
    2.97      /* A table mapping each PFN to its new MFN. */
    2.98      unsigned long *pfn_to_mfn_table = NULL;
    2.99 @@ -110,126 +82,68 @@ int xc_linux_restore(int xc_handle, XcIO
   2.100      struct mmuext_op pin[MAX_PIN_BATCH];
   2.101      unsigned int nr_pins = 0;
   2.102  
   2.103 -    xcio_info(ioctxt, "xc_linux_restore start\n");
   2.104 +    DPRINTF("xc_linux_restore start\n");
   2.105  
   2.106 -    if ( mlock(&ctxt, sizeof(ctxt) ) )
   2.107 -    {
   2.108 +    if (mlock(&ctxt, sizeof(ctxt))) {
   2.109          /* needed for when we do the build dom0 op, 
   2.110             but might as well do early */
   2.111 -        PERROR("Unable to mlock ctxt");
   2.112 +        ERR("Unable to mlock ctxt");
   2.113          return 1;
   2.114      }
   2.115  
   2.116 -    /* Start reading the saved-domain record. */
   2.117 -    if ( xcio_read(ioctxt, signature, 16) ||
   2.118 -         (memcmp(signature, "LinuxGuestRecord", 16) != 0) )
   2.119 -    {
   2.120 -        xcio_error(ioctxt, "Unrecognised state format -- no signature found");
   2.121 -        goto out;
   2.122 -    }
   2.123 -
   2.124 -    if ( xcio_read(ioctxt, &nr_pfns,              sizeof(unsigned long)) ||
   2.125 -         xcio_read(ioctxt, pfn_to_mfn_frame_list, PAGE_SIZE) )
   2.126 -    {
   2.127 -        xcio_error(ioctxt, "Error reading header");
   2.128 -        goto out;
   2.129 -    }
   2.130 +    /* We want zeroed memory so use calloc rather than malloc. */
   2.131 +    pfn_to_mfn_table = calloc(4, nr_pfns);
   2.132 +    pfn_type = calloc(4, nr_pfns);    
   2.133 +    region_mfn = calloc(4, MAX_BATCH_SIZE);
   2.134  
   2.135 -    if ( read_vmconfig(ioctxt) )
   2.136 -    {
   2.137 -        xcio_error(ioctxt, "Error writing vmconfig");
   2.138 -        goto out;
   2.139 -    }
   2.140 -
   2.141 -    if ( nr_pfns > 1024*1024 )
   2.142 -    {
   2.143 -        xcio_error(ioctxt, "Invalid state file -- pfn count out of range");
   2.144 -        goto out;
   2.145 -    }
   2.146 -
   2.147 -    /* We want zeroed memory so use calloc rather than malloc. */
   2.148 -    pfn_to_mfn_table = calloc(1, 4 * nr_pfns);
   2.149 -    pfn_type         = calloc(1, 4 * nr_pfns);    
   2.150 -    region_mfn       = calloc(1, 4 * MAX_BATCH_SIZE);    
   2.151 -
   2.152 -    if ( (pfn_to_mfn_table == NULL) ||
   2.153 -         (pfn_type == NULL) || 
   2.154 -         (region_mfn == NULL) ) 
   2.155 -    {
   2.156 +    if ((pfn_to_mfn_table == NULL) || (pfn_type == NULL) || 
   2.157 +        (region_mfn == NULL)) {
   2.158 +        ERR("memory alloc failed");
   2.159          errno = ENOMEM;
   2.160          goto out;
   2.161      }
   2.162      
   2.163 -    if ( mlock(region_mfn, 4 * MAX_BATCH_SIZE ) )
   2.164 -    {
   2.165 -        xcio_error(ioctxt, "Could not mlock region_mfn");
   2.166 -        goto out;
   2.167 -    }
   2.168 -
   2.169 -    /* Create domain on CPU -1 so that it may auto load-balance in future. */
   2.170 -    if ( xc_domain_create(xc_handle, &dom) )
   2.171 -    {
   2.172 -        xcio_error(ioctxt, "Could not create domain.");
   2.173 -        goto out;
   2.174 -    }
   2.175 -    if ( xc_domain_setcpuweight(xc_handle, dom, 1) )
   2.176 -    {
   2.177 -        xcio_error(ioctxt, "Could not set domain cpuweight.");
   2.178 +    if (mlock(region_mfn, 4 * MAX_BATCH_SIZE)) {
   2.179 +        ERR("Could not mlock region_mfn");
   2.180          goto out;
   2.181      }
   2.182 -    if ( xc_domain_setmaxmem(xc_handle, dom, nr_pfns * (PAGE_SIZE / 1024)) )
   2.183 -    {
   2.184 -        xcio_error(ioctxt, "Could not set domain maxmem. pfns=%ld, %ldKB",
   2.185 -                   nr_pfns, nr_pfns * (PAGE_SIZE / 1024));
   2.186 -        goto out;
   2.187 -    }
   2.188 -    if ( xc_domain_memory_increase_reservation(xc_handle, dom,
   2.189 -                                               nr_pfns * (PAGE_SIZE / 1024)) )
   2.190 -    {
   2.191 -        xcio_error(ioctxt,
   2.192 -                   "Could not increase domain memory reservation. pfns=%ld",
   2.193 -                   nr_pfns);
   2.194 -        goto out;
   2.195 -    }
   2.196 -
   2.197 -    ioctxt->domain = dom;
   2.198 -    xcio_info(ioctxt, "Created domain %u\n", dom);
   2.199  
   2.200      /* Get the domain's shared-info frame. */
   2.201      op.cmd = DOM0_GETDOMAININFO;
   2.202      op.u.getdomaininfo.domain = (domid_t)dom;
   2.203 -    if ( do_dom0_op(xc_handle, &op) < 0 )
   2.204 -    {
   2.205 -        xcio_error(ioctxt, "Could not get information on new domain");
   2.206 +    if (do_dom0_op(xc_handle, &op) < 0) {
   2.207 +        ERR("Could not get information on new domain");
   2.208          goto out;
   2.209      }
   2.210      shared_info_frame = op.u.getdomaininfo.shared_info_frame;
   2.211  
   2.212 -    if(ioctxt->flags & XCFLAGS_CONFIGURE)
   2.213 -    {
   2.214 -        if(xcio_configure_domain(ioctxt))
   2.215 -        {
   2.216 -           xcio_error(ioctxt, "Configuring domain failed"); 
   2.217 -           goto out;
   2.218 -        }
   2.219 +    err = xc_domain_setmaxmem(xc_handle, dom, nr_pfns * PAGE_SIZE / 1024);
   2.220 +    if (err != 0) {
   2.221 +        errno = ENOMEM;
   2.222 +        goto out;
   2.223 +    }
   2.224 +
   2.225 +    err = xc_domain_memory_increase_reservation(xc_handle, dom,
   2.226 +                                                nr_pfns * PAGE_SIZE / 1024);
   2.227 +    if (err != 0) {
   2.228 +        errno = ENOMEM;
   2.229 +        goto out;
   2.230      }
   2.231  
   2.232      /* Build the pfn-to-mfn table. We choose MFN ordering returned by Xen. */
   2.233 -    if ( xc_get_pfn_list(xc_handle, dom, 
   2.234 -                         pfn_to_mfn_table, nr_pfns) != nr_pfns )
   2.235 -    {
   2.236 -        xcio_error(ioctxt, "Did not read correct number of frame "
   2.237 -                   "numbers for new dom");
   2.238 +    if (xc_get_pfn_list(xc_handle, dom, pfn_to_mfn_table, nr_pfns) !=
   2.239 +        nr_pfns) {
   2.240 +        ERR("Did not read correct number of frame numbers for new dom");
   2.241          goto out;
   2.242      }
   2.243  
   2.244 -    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
   2.245 -    {
   2.246 -        xcio_error(ioctxt, "Could not initialise for MMU updates");
   2.247 +    mmu = init_mmu_updates(xc_handle, dom);
   2.248 +    if (mmu == NULL) {
   2.249 +        ERR("Could not initialise for MMU updates");
   2.250          goto out;
   2.251      }
   2.252  
   2.253 -    xcio_info(ioctxt, "Reloading memory pages:   0%%");
   2.254 +    DPRINTF("Reloading memory pages:   0%%");
   2.255  
   2.256      /*
   2.257       * Now simply read each saved frame into its new machine frame.
   2.258 @@ -246,17 +160,17 @@ int xc_linux_restore(int xc_handle, XcIO
   2.259          this_pc = (n * 100) / nr_pfns;
   2.260          if ( (this_pc - prev_pc) >= 5 )
   2.261          {
   2.262 -            xcio_info(ioctxt, "\b\b\b\b%3d%%", this_pc);
   2.263 +            PPRINTF("\b\b\b\b%3d%%", this_pc);
   2.264              prev_pc = this_pc;
   2.265          }
   2.266  
   2.267 -        if ( xcio_read(ioctxt, &j, sizeof(int)) )
   2.268 +        if ( read(io_fd, &j, sizeof(int)) != sizeof(int) )
   2.269          {
   2.270 -            xcio_error(ioctxt, "Error when reading from state file");
   2.271 +            ERR("Error when reading from state file");
   2.272              goto out;
   2.273          }
   2.274  
   2.275 -        DPRINTF("batch %d\n",j);
   2.276 +        PPRINTF("batch %d\n",j);
   2.277   
   2.278          if ( j == -1 )
   2.279          {
   2.280 @@ -270,12 +184,13 @@ int xc_linux_restore(int xc_handle, XcIO
   2.281  
   2.282          if ( j > MAX_BATCH_SIZE )
   2.283          {
   2.284 -            xcio_error(ioctxt, "Max batch size exceeded. Giving up.");
   2.285 +            ERR("Max batch size exceeded. Giving up.");
   2.286              goto out;
   2.287          }
   2.288   
   2.289 -        if ( xcio_read(ioctxt, region_pfn_type, j*sizeof(unsigned long)) ) {
   2.290 -            xcio_error(ioctxt, "Error when reading from state file");
   2.291 +        if ( read(io_fd, region_pfn_type, j*sizeof(unsigned long)) !=
   2.292 +             j*sizeof(unsigned long) ) {
   2.293 +            ERR("Error when reading from state file");
   2.294              goto out;
   2.295          }
   2.296  
   2.297 @@ -297,7 +212,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.298                                                    region_mfn,
   2.299                                                    j )) == 0 )
   2.300          {
   2.301 -            xcio_error(ioctxt, "map batch failed");
   2.302 +            ERR("map batch failed");
   2.303              goto out;
   2.304          }
   2.305  
   2.306 @@ -311,7 +226,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.307  
   2.308              if (pfn>nr_pfns)
   2.309              {
   2.310 -                xcio_error(ioctxt, "pfn out of range");
   2.311 +                ERR("pfn out of range");
   2.312                  goto out;
   2.313              }
   2.314  
   2.315 @@ -326,9 +241,9 @@ int xc_linux_restore(int xc_handle, XcIO
   2.316              else
   2.317                  ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
   2.318  
   2.319 -            if ( xcio_read(ioctxt, ppage, PAGE_SIZE) )
   2.320 +            if ( read(io_fd, ppage, PAGE_SIZE) != PAGE_SIZE )
   2.321              {
   2.322 -                xcio_error(ioctxt, "Error when reading from state file");
   2.323 +                ERR("Error when reading from state file");
   2.324                  goto out;
   2.325              }
   2.326  
   2.327 @@ -346,7 +261,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.328                          xpfn = ppage[k] >> PAGE_SHIFT;
   2.329                          if ( xpfn >= nr_pfns )
   2.330                          {
   2.331 -                            xcio_error(ioctxt, "Frame number in type %lu page "
   2.332 +                            ERR("Frame number in type %lu page "
   2.333                                         "table is out of range. i=%d k=%d "
   2.334                                         "pfn=0x%lx nr_pfns=%lu", 
   2.335                                         region_pfn_type[i]>>28, i, 
   2.336 @@ -374,7 +289,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.337  
   2.338                          if ( xpfn >= nr_pfns )
   2.339                          {
   2.340 -                            xcio_error(ioctxt, "Frame number in type %lu page"
   2.341 +                            ERR("Frame number in type %lu page"
   2.342                                         " table is out of range. i=%d k=%d "
   2.343                                         "pfn=%lu nr_pfns=%lu",
   2.344                                         region_pfn_type[i]>>28, i, k, 
   2.345 @@ -391,7 +306,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.346              break;
   2.347  
   2.348              default:
   2.349 -                xcio_error(ioctxt, "Bogus page type %lx page table is "
   2.350 +                ERR("Bogus page type %lx page table is "
   2.351                             "out of range. i=%d nr_pfns=%lu", 
   2.352                             region_pfn_type[i], i, nr_pfns);
   2.353                  goto out;
   2.354 @@ -432,7 +347,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.355          n+=j; /* crude stats */
   2.356      }
   2.357  
   2.358 -    xcio_info(ioctxt, "Received all pages\n");
   2.359 +    DPRINTF("Received all pages\n");
   2.360  
   2.361      if ( finish_mmu_updates(xc_handle, mmu) )
   2.362          goto out;
   2.363 @@ -462,30 +377,31 @@ int xc_linux_restore(int xc_handle, XcIO
   2.364           (do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
   2.365          goto out;
   2.366  
   2.367 -    xcio_info(ioctxt, "\b\b\b\b100%%\n");
   2.368 -    xcio_info(ioctxt, "Memory reloaded.\n");
   2.369 +    DPRINTF("\b\b\b\b100%%\n");
   2.370 +    DPRINTF("Memory reloaded.\n");
   2.371  
   2.372      /* Get the list of PFNs that are not in the psuedo-phys map */
   2.373      {
   2.374  	unsigned int count, *pfntab;
   2.375  	int rc;
   2.376  
   2.377 -	if ( xcio_read(ioctxt, &count, sizeof(count)) )
   2.378 +	if ( read(io_fd, &count, sizeof(count)) != sizeof(count) )
   2.379  	{
   2.380 -	    xcio_error(ioctxt, "Error when reading from state file");
   2.381 +	    ERR("Error when reading from state file");
   2.382  	    goto out;
   2.383  	}
   2.384  
   2.385  	pfntab = malloc( sizeof(unsigned int) * count );
   2.386  	if ( pfntab == NULL )
   2.387  	{
   2.388 -	    xcio_error(ioctxt, "Out of memory");
   2.389 +	    ERR("Out of memory");
   2.390  	    goto out;
   2.391  	}
   2.392  
   2.393 -	if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) )
   2.394 +	if ( read(io_fd, pfntab, sizeof(unsigned int)*count) !=
   2.395 +             sizeof(unsigned int)*count )
   2.396  	{
   2.397 -	    xcio_error(ioctxt, "Error when reading pfntab from state file");
   2.398 +	    ERR("Error when reading pfntab from state file");
   2.399  	    goto out;
   2.400  	}
   2.401  
   2.402 @@ -502,7 +418,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.403  				       MEMOP_decrease_reservation,
   2.404  				       pfntab, count, 0, dom )) <0 )
   2.405  	    {
   2.406 -		xcio_error(ioctxt, "Could not decrease reservation : %d",rc);
   2.407 +		ERR("Could not decrease reservation : %d",rc);
   2.408  		goto out;
   2.409  	    }
   2.410  	    else
   2.411 @@ -512,10 +428,10 @@ int xc_linux_restore(int xc_handle, XcIO
   2.412  	}	
   2.413      }
   2.414  
   2.415 -    if ( xcio_read(ioctxt, &ctxt,            sizeof(ctxt)) ||
   2.416 -         xcio_read(ioctxt, shared_info_page, PAGE_SIZE) )
   2.417 +    if ( read(io_fd, &ctxt,            sizeof(ctxt)) != sizeof(ctxt) ||
   2.418 +         read(io_fd, shared_info_page, PAGE_SIZE) != PAGE_SIZE )
   2.419      {
   2.420 -        xcio_error(ioctxt, "Error when reading from state file");
   2.421 +        ERR("Error when reading from state file");
   2.422          goto out;
   2.423      }
   2.424  
   2.425 @@ -523,7 +439,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.426      pfn = ctxt.user_regs.esi;
   2.427      if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
   2.428      {
   2.429 -        xcio_error(ioctxt, "Suspend record frame number is bad");
   2.430 +        ERR("Suspend record frame number is bad");
   2.431          goto out;
   2.432      }
   2.433      ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
   2.434 @@ -537,7 +453,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.435      /* Uncanonicalise each GDT frame number. */
   2.436      if ( ctxt.gdt_ents > 8192 )
   2.437      {
   2.438 -        xcio_error(ioctxt, "GDT entry count out of range");
   2.439 +        ERR("GDT entry count out of range");
   2.440          goto out;
   2.441      }
   2.442  
   2.443 @@ -546,7 +462,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.444          pfn = ctxt.gdt_frames[i];
   2.445          if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
   2.446          {
   2.447 -            xcio_error(ioctxt, "GDT frame number is bad");
   2.448 +            ERR("GDT frame number is bad");
   2.449              goto out;
   2.450          }
   2.451          ctxt.gdt_frames[i] = pfn_to_mfn_table[pfn];
   2.452 @@ -558,7 +474,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.453      {
   2.454          printf("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx\n",
   2.455                 pfn, nr_pfns, pfn_type[pfn], (unsigned long)L2TAB);
   2.456 -        xcio_error(ioctxt, "PT base is bad.");
   2.457 +        ERR("PT base is bad.");
   2.458          goto out;
   2.459      }
   2.460      ctxt.pt_base = pfn_to_mfn_table[pfn] << PAGE_SHIFT;
   2.461 @@ -583,7 +499,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.462          pfn = pfn_to_mfn_frame_list[i];
   2.463          if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
   2.464          {
   2.465 -            xcio_error(ioctxt, "PFN-to-MFN frame number is bad");
   2.466 +            ERR("PFN-to-MFN frame number is bad");
   2.467              goto out;
   2.468          }
   2.469          mfn = pfn_to_mfn_table[pfn];
   2.470 @@ -596,7 +512,7 @@ int xc_linux_restore(int xc_handle, XcIO
   2.471                                 pfn_to_mfn_frame_list,
   2.472                                 (nr_pfns+1023)/1024 )) == 0 )
   2.473      {
   2.474 -        xcio_error(ioctxt, "Couldn't map pfn_to_mfn table");
   2.475 +        ERR("Couldn't map pfn_to_mfn table");
   2.476          goto out;
   2.477      }
   2.478  
   2.479 @@ -636,11 +552,11 @@ int xc_linux_restore(int xc_handle, XcIO
   2.480           (ctxt.ldt_base > HYPERVISOR_VIRT_START) ||
   2.481           ((ctxt.ldt_base + ctxt.ldt_ents*8) > HYPERVISOR_VIRT_START) )
   2.482      {
   2.483 -        xcio_error(ioctxt, "Bad LDT base or size");
   2.484 +        ERR("Bad LDT base or size");
   2.485          goto out;
   2.486      }
   2.487  
   2.488 -    xcio_info(ioctxt, "Domain ready to be built.\n");
   2.489 +    DPRINTF("Domain ready to be built.\n");
   2.490  
   2.491      op.cmd = DOM0_SETDOMAININFO;
   2.492      op.u.setdomaininfo.domain = (domid_t)dom;
   2.493 @@ -650,26 +566,20 @@ int xc_linux_restore(int xc_handle, XcIO
   2.494  
   2.495      if ( rc != 0 )
   2.496      {
   2.497 -        xcio_error(ioctxt, "Couldn't build the domain");
   2.498 +        ERR("Couldn't build the domain");
   2.499          goto out;
   2.500      }
   2.501  
   2.502 -    if ( ioctxt->flags & XCFLAGS_CONFIGURE )
   2.503 -    {
   2.504 -        xcio_info(ioctxt, "Domain ready to be unpaused\n");
   2.505 -        op.cmd = DOM0_UNPAUSEDOMAIN;
   2.506 -        op.u.unpausedomain.domain = (domid_t)dom;
   2.507 -        rc = do_dom0_op(xc_handle, &op);
   2.508 -    }
   2.509 -
   2.510 -    if ( rc == 0 )
   2.511 -    {
   2.512 +    DPRINTF("Domain ready to be unpaused\n");
   2.513 +    op.cmd = DOM0_UNPAUSEDOMAIN;
   2.514 +    op.u.unpausedomain.domain = (domid_t)dom;
   2.515 +    rc = do_dom0_op(xc_handle, &op);
   2.516 +    if (rc == 0) {
   2.517          /* Success: print the domain id. */
   2.518 -        xcio_info(ioctxt, "DOM=%u\n", dom);
   2.519 +        DPRINTF("DOM=%u\n", dom);
   2.520          return 0;
   2.521      }
   2.522  
   2.523 -
   2.524   out:
   2.525      if ( (rc != 0) && (dom != 0) )
   2.526          xc_domain_destroy(xc_handle, dom);
   2.527 @@ -680,9 +590,6 @@ int xc_linux_restore(int xc_handle, XcIO
   2.528      if ( pfn_type != NULL )
   2.529          free(pfn_type);
   2.530  
   2.531 -    if ( rc == 0 )
   2.532 -        ioctxt->domain = dom;
   2.533 -
   2.534 -    DPRINTF("Restore exit with rc=%d\n",rc);
   2.535 +    DPRINTF("Restore exit with rc=%d\n", rc);
   2.536      return rc;
   2.537  }
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri May 20 15:23:48 2005 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri May 20 19:25:46 2005 +0000
     3.3 @@ -334,62 +334,41 @@ static PyObject *pyxc_linux_save(PyObjec
     3.4      return val;
     3.5  }
     3.6  
     3.7 -
     3.8 -static int file_restore(XcObject *xc, XcIOContext *ioctxt, char *state_file)
     3.9 -{
    3.10 -    int rc = -1;
    3.11 -
    3.12 -    ioctxt->io = gzip_stream_fopen(state_file, "rb");
    3.13 -    if ( ioctxt->io == NULL )
    3.14 -    {
    3.15 -        xcio_perror(ioctxt, "Could not open file for reading");
    3.16 -        return rc;
    3.17 -    }
    3.18 -
    3.19 -    rc = xc_linux_restore(xc->xc_handle, ioctxt);
    3.20 -
    3.21 -    IOStream_close(ioctxt->io);
    3.22 -    
    3.23 -    return rc;
    3.24 -}
    3.25 -
    3.26  static PyObject *pyxc_linux_restore(PyObject *self,
    3.27                                      PyObject *args,
    3.28                                      PyObject *kwds)
    3.29  {
    3.30      XcObject *xc = (XcObject *)self;
    3.31 -    char *state_file;
    3.32 -    int progress = 1, debug = 0;
    3.33      PyObject *val = NULL;
    3.34 -    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
    3.35      int rc =-1;
    3.36 +    int io_fd, dom;
    3.37 +    unsigned long nr_pfns;
    3.38 +    char *pfn2mfn;
    3.39 +    int pfn2mfn_len;
    3.40 +    PyObject *pfn2mfn_object;
    3.41  
    3.42 -    static char *kwd_list[] = { "state_file", "progress", "debug", NULL };
    3.43 +    static char *kwd_list[] = { "fd", "dom", "pfns", "pfn2mfn", NULL };
    3.44  
    3.45 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s|ii", kwd_list,
    3.46 -                                      &state_file,
    3.47 -                                      &progress,
    3.48 -                                      &debug) )
    3.49 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iilO", kwd_list,
    3.50 +                                      &io_fd, &dom, &nr_pfns,
    3.51 +				      &pfn2mfn_object) )
    3.52          goto exit;
    3.53  
    3.54 -    if ( progress )
    3.55 -        ioctxt.flags |= XCFLAGS_VERBOSE;
    3.56 -    if ( debug )
    3.57 -        ioctxt.flags |= XCFLAGS_DEBUG;
    3.58 +    if (PyString_AsStringAndSize(pfn2mfn_object, &pfn2mfn, &pfn2mfn_len))
    3.59 +	goto exit;
    3.60  
    3.61 -    if ( (state_file == NULL) || (state_file[0] == '\0') )
    3.62 -        goto exit;
    3.63 +    if (pfn2mfn_len != PAGE_SIZE)
    3.64 +	goto exit;
    3.65  
    3.66 -    rc = file_restore(xc, &ioctxt, state_file);
    3.67 +    rc = xc_linux_restore(xc->xc_handle, io_fd, dom, nr_pfns, pfn2mfn);
    3.68      if ( rc != 0 )
    3.69      {
    3.70          PyErr_SetFromErrno(xc_error);
    3.71          goto exit;
    3.72      }
    3.73  
    3.74 -    val = Py_BuildValue("{s:i,s:s}",
    3.75 -                        "dom", ioctxt.domain,
    3.76 -                        "vmconfig", ioctxt.vmconfig);
    3.77 +    Py_INCREF(zero);
    3.78 +    val = zero;
    3.79  
    3.80    exit:
    3.81      return val;
    3.82 @@ -1061,8 +1040,9 @@ static PyMethodDef pyxc_methods[] = {
    3.83        (PyCFunction)pyxc_linux_restore, 
    3.84        METH_VARARGS | METH_KEYWORDS, "\n"
    3.85        "Restore the CPU and memory state of a Linux guest OS.\n"
    3.86 -      " state_file [str]:    Name of state file. Must not currently exist.\n"
    3.87 -      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
    3.88 +      " dom        [int]:    Identifier of domain to be restored.\n"
    3.89 +      " pfns       [int]:    Number of pages domain uses.\n"
    3.90 +      " pfn2mfn    [str]:    String containing the pfn to mfn frame list.\n\n"
    3.91        "Returns: [int] new domain identifier on success; -1 on error.\n" },
    3.92  
    3.93      { "linux_build", 
     4.1 --- a/tools/python/xen/xend/XendDomain.py	Fri May 20 15:23:48 2005 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri May 20 19:25:46 2005 +0000
     4.3 @@ -24,6 +24,9 @@ import scheduler
     4.4  from xen.xend.server import channel
     4.5  
     4.6  
     4.7 +import errno
     4.8 +from struct import pack, unpack, calcsize
     4.9 +
    4.10  __all__ = [ "XendDomain" ]
    4.11  
    4.12  SHUTDOWN_TIMEOUT = 30
    4.13 @@ -298,7 +301,7 @@ class XendDomain:
    4.14                             [dominfo.name, dominfo.id, "fail"])
    4.15          return dominfo
    4.16  
    4.17 -    def domain_configure(self, id, vmconfig):
    4.18 +    def domain_configure(self, vmconfig):
    4.19          """Configure an existing domain. This is intended for internal
    4.20          use by domain restore and migrate.
    4.21  
    4.22 @@ -306,10 +309,7 @@ class XendDomain:
    4.23          @param vmconfig: vm configuration
    4.24          """
    4.25          config = sxp.child_value(vmconfig, 'config')
    4.26 -        dominfo = self.domain_lookup(id)
    4.27 -        log.debug('domain_configure> id=%s config=%s', str(id), str(config))
    4.28 -        if dominfo.config:
    4.29 -            raise XendError("Domain already configured: " + dominfo.id)
    4.30 +        dominfo = XendDomainInfo.tmp_restore_create_domain()
    4.31          dominfo.dom_construct(dominfo.dom, config)
    4.32          self._add_domain(dominfo)
    4.33          return dominfo
    4.34 @@ -320,8 +320,65 @@ class XendDomain:
    4.35          @param src:      source file
    4.36          @param progress: output progress if true
    4.37          """
    4.38 -        xmigrate = XendMigrate.instance()
    4.39 -        return xmigrate.restore_begin(src)
    4.40 +
    4.41 +        SIGNATURE = "LinuxGuestRecord"
    4.42 +        sizeof_int = calcsize("L")
    4.43 +        sizeof_unsigned_long = calcsize("i")
    4.44 +        PAGE_SIZE = 4096
    4.45 +
    4.46 +        class XendFile(file):
    4.47 +            def read_exact(self, size, error_msg):
    4.48 +                buf = self.read(size)
    4.49 +                if len(buf) != size:
    4.50 +                    raise XendError(error_msg)
    4.51 +                return buf
    4.52 +        
    4.53 +        try:
    4.54 +            fd = XendFile(src, 'rb')
    4.55 +
    4.56 +            signature = fd.read_exact(len(SIGNATURE),
    4.57 +                "not a valid guest state file: signature read")
    4.58 +            if signature != SIGNATURE:
    4.59 +                raise XendError("not a valid guest state file: found '%s'" %
    4.60 +                                signature)
    4.61 +
    4.62 +            l = fd.read_exact(sizeof_unsigned_long,
    4.63 +                              "not a valid guest state file: pfn count read")
    4.64 +            nr_pfns = unpack("=L", l)[0]   # XXX endianess
    4.65 +            if nr_pfns > 1024*1024:     # XXX
    4.66 +                raise XendError(
    4.67 +                    "not a valid guest state file: pfn count out of range")
    4.68 +
    4.69 +            pfn_to_mfn_frame_list = fd.read_exact(PAGE_SIZE,
    4.70 +                "not a valid guest state file: pfn_to_mfn_frame_list read")
    4.71 +
    4.72 +            l = fd.read_exact(sizeof_int,
    4.73 +                              "not a valid guest state file: config size read")
    4.74 +            vmconfig_size = unpack("i", l)[0] # XXX endianess
    4.75 +            vmconfig_buf = fd.read_exact(vmconfig_size,
    4.76 +                "not a valid guest state file: config read")
    4.77 +
    4.78 +            p = sxp.Parser()
    4.79 +            p.input(vmconfig_buf)
    4.80 +            if not p.ready:
    4.81 +                raise XendError("not a valid guest state file: config parse")
    4.82 +
    4.83 +            vmconfig = p.get_val()
    4.84 +            dominfo = self.domain_configure(vmconfig)
    4.85 +
    4.86 +            # XXXcl hack: fd.tell will sync up the object and
    4.87 +            #             underlying file descriptor
    4.88 +            ignore = fd.tell()
    4.89 +
    4.90 +            xc.linux_restore(fd.fileno(), int(dominfo.id), nr_pfns,
    4.91 +                             pfn_to_mfn_frame_list)
    4.92 +            return dominfo
    4.93 +
    4.94 +        except IOError, ex:
    4.95 +            if ex.errno == errno.ENOENT:
    4.96 +                raise XendError("can't open guest state file %s" % src)
    4.97 +            else:
    4.98 +                raise
    4.99      
   4.100      def domain_get(self, id):
   4.101          """Get up-to-date info about a domain.
     5.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri May 20 15:23:48 2005 +0000
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri May 20 19:25:46 2005 +0000
     5.3 @@ -183,6 +183,13 @@ def vm_create(config):
     5.4      vm.construct(config)
     5.5      return vm
     5.6  
     5.7 +def tmp_restore_create_domain():
     5.8 +    # dom input parameter is ignored
     5.9 +    vm = XendDomainInfo()
    5.10 +    dom = xc.domain_create()
    5.11 +    vm.setdom(dom)
    5.12 +    return vm
    5.13 +
    5.14  def vm_recreate(savedinfo, info):
    5.15      """Create the VM object for an existing domain.
    5.16  
     6.1 --- a/tools/xfrd/xen_domain.c	Fri May 20 15:23:48 2005 +0000
     6.2 +++ b/tools/xfrd/xen_domain.c	Fri May 20 19:25:46 2005 +0000
     6.3 @@ -87,6 +87,7 @@ int xen_domain_rcv(IOStream *io,
     6.4                     char **vmconfig, int *vmconfig_n,
     6.5                     int *configured){
     6.6      int err = 0;
     6.7 +#if 0
     6.8      XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
     6.9      dprintf(">\n");
    6.10      ioctxt->io = io;
    6.11 @@ -102,6 +103,7 @@ int xen_domain_rcv(IOStream *io,
    6.12      *vmconfig_n = ioctxt->vmconfig_n;
    6.13      *configured = (ioctxt->flags & XCFLAGS_CONFIGURE);
    6.14      dprintf("< err=%d\n", err);
    6.15 +#endif
    6.16      return err;
    6.17  }
    6.18