ia64/xen-unstable

changeset 5054:95c16a18cc65

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
author cl349@firebug.cl.cam.ac.uk
date Fri May 20 19:26:10 2005 +0000 (2005-05-20)
parents 6cc3680e98d1 fb7d59789e4d
children 8397cf88a855
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 17:01:23 2005 +0000
     1.2 +++ b/tools/libxc/xc.h	Fri May 20 19:26:10 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 17:01:23 2005 +0000
     2.2 +++ b/tools/libxc/xc_linux_restore.c	Fri May 20 19:26:10 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 17:01:23 2005 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri May 20 19:26:10 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 17:01:23 2005 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri May 20 19:26:10 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 17:01:23 2005 +0000
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri May 20 19:26:10 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 17:01:23 2005 +0000
     6.2 +++ b/tools/xfrd/xen_domain.c	Fri May 20 19:26:10 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