ia64/xen-unstable

changeset 5121:478f75e49113

bitkeeper revision 1.1527.2.1 (429368a2F0SR4yrzuHsrRucuwriYqA)

Implement the parts of vm save which need interaction with xend
as part of xend, instead of using xfrd.
Execute xc_linux_save in a seperate process so that it can't
crash xend. Also handle errors passed from xc_linux_save.
xen_domain.c:
Disable save in xfrd.
xc_save.c:
new file
Makefile:
Add xc_save.
XendDomainInfo.py:
Add suspended state and threading Condition with notification, allowing
easy waiting for state changes.
XendDomain.py:
Implement the parts of vm save which need interaction with xend
as part of xend, instead of using xfrd. Set state to "suspended"
when detecting a suspended domain.
Fix reading output from subprocesses.
Fix ValueError in xen_domain().
xc.c:
Remove python binding for xc_linux_save.
xc_linux_save.c:
Implement the parts of vm save which need interaction with xend
as part of xend, instead of using xfrd. Also run xc_linux_save
in a seperate process.
xc_linux_restore.c:
Flush output so that xend picks it up timely.
Also disable debug output again.
xc.h:
Update xc_linux_save prototype and fix comments for xc_linux_{save,restore}.
ignore:
Add tools/xcutils/xc_save.
xpopen.py:
Exit with 127 if exec fails.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Tue May 24 17:47:14 2005 +0000 (2005-05-24)
parents 6c5699e95a56
children 734ebf0aa35f
files .rootkeys BitKeeper/etc/ignore tools/libxc/xc.h tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/util/xpopen.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/xcutils/Makefile tools/xcutils/xc_save.c tools/xfrd/xen_domain.c
line diff
     1.1 --- a/.rootkeys	Tue May 24 09:42:24 2005 +0000
     1.2 +++ b/.rootkeys	Tue May 24 17:47:14 2005 +0000
     1.3 @@ -1032,6 +1032,7 @@ 41d58ba6qyr2BkTcH2WlNBYLRyl2Yw tools/xcs
     1.4  41d58ba6ijEF6fedqRO5vFu7uCirZg tools/xcs/xcsdump.c
     1.5  4292540couq-V0TPwyQ6bspNEWNcvw tools/xcutils/Makefile
     1.6  42925407VysDb9O06OK_RUzTZxfLoA tools/xcutils/xc_restore.c
     1.7 +42936745WTLYamYsmXm_JGJ72JX-_Q tools/xcutils/xc_save.c
     1.8  403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile
     1.9  40a107afN60pFdURgBv9KwEzgRl5mQ tools/xentrace/formats
    1.10  420d52d2_znVbT4JAPIU36vQOme83g tools/xentrace/xenctx.c
     2.1 --- a/BitKeeper/etc/ignore	Tue May 24 09:42:24 2005 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Tue May 24 17:47:14 2005 +0000
     2.3 @@ -127,6 +127,7 @@ tools/x2d2/minixend
     2.4  tools/xcs/xcs
     2.5  tools/xcs/xcsdump
     2.6  tools/xcutils/xc_restore
     2.7 +tools/xcutils/xc_save
     2.8  tools/xentrace/xentrace
     2.9  tools/xfrd/xfrd
    2.10  xen/BLOG
     3.1 --- a/tools/libxc/xc.h	Tue May 24 09:42:24 2005 +0000
     3.2 +++ b/tools/libxc/xc.h	Tue May 24 17:47:14 2005 +0000
     3.3 @@ -225,23 +225,22 @@ int xc_shadow_control(int xc_handle,
     3.4  struct XcIOContext;
     3.5  
     3.6  /**
     3.7 - * This function will save a domain running Linux to an IO context.  This
     3.8 - * IO context is currently a private interface making this function difficult
     3.9 - * to call.  It's interface will likely change in the future.
    3.10 + * This function will save a domain running Linux.
    3.11   *
    3.12   * @parm xc_handle a handle to an open hypervisor interface
    3.13 - * @parm ioctxt the IO context to save a domain to
    3.14 + * @parm fd the file descriptor to save a domain to
    3.15 + * @parm dom the id of the domain
    3.16   * @return 0 on success, -1 on failure
    3.17   */
    3.18 -int xc_linux_save(int xc_handle, struct XcIOContext *ioctxt);
    3.19 +int xc_linux_save(int xc_handle, int fd, u32 dom);
    3.20  
    3.21  /**
    3.22 - * This function will restore a saved domain running Linux to an IO context.
    3.23 - * Like xc_linux_save(), this function uses a parameter who's structure is
    3.24 - * privately defined.  It's interface will also likely change.
    3.25 + * This function will restore a saved domain running Linux.
    3.26   *
    3.27   * @parm xc_handle a handle to an open hypervisor interface
    3.28 - * @parm ioctxt the IO context to restore a domain from
    3.29 + * @parm fd the file descriptor to restore a domain from
    3.30 + * @parm dom the id of the domain
    3.31 + * @parm nr_pfns the number of pages
    3.32   * @return 0 on success, -1 on failure
    3.33   */
    3.34  int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns);
     4.1 --- a/tools/libxc/xc_linux_restore.c	Tue May 24 09:42:24 2005 +0000
     4.2 +++ b/tools/libxc/xc_linux_restore.c	Tue May 24 17:47:14 2005 +0000
     4.3 @@ -11,23 +11,23 @@
     4.4  
     4.5  #define MAX_BATCH_SIZE 1024
     4.6  
     4.7 -#define DEBUG 01
     4.8 +#define DEBUG 0
     4.9  
    4.10  #if 1
    4.11 -#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
    4.12 +#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a ); fflush(stderr)
    4.13  #else
    4.14  #define ERR(_f, _a...) ((void)0)
    4.15  #endif
    4.16  
    4.17  #if DEBUG
    4.18 -#define DPRINTF(_f, _a...) fprintf ( stdout, _f , ## _a )
    4.19 +#define DPRINTF(_f, _a...) fprintf ( stdout, _f , ## _a ); fflush(stdout)
    4.20  #else
    4.21  #define DPRINTF(_f, _a...) ((void)0)
    4.22  #endif
    4.23  
    4.24  #define PROGRESS 0
    4.25  #if PROGRESS
    4.26 -#define PPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
    4.27 +#define PPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a ); fflush(stderr)
    4.28  #else
    4.29  #define PPRINTF(_f, _a...)
    4.30  #endif
     5.1 --- a/tools/libxc/xc_linux_save.c	Tue May 24 09:42:24 2005 +0000
     5.2 +++ b/tools/libxc/xc_linux_save.c	Tue May 24 17:47:14 2005 +0000
     5.3 @@ -17,19 +17,25 @@
     5.4  
     5.5  #define MAX_MBIT_RATE 500
     5.6  
     5.7 -#define DEBUG  0
     5.8 -#define DDEBUG 0
     5.9 +#define DEBUG 0
    5.10 +
    5.11 +#if 1
    5.12 +#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
    5.13 +#else
    5.14 +#define ERR(_f, _a...) ((void)0)
    5.15 +#endif
    5.16  
    5.17  #if DEBUG
    5.18 -#define DPRINTF(_f, _a...) printf ( _f , ## _a )
    5.19 +#define DPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
    5.20  #else
    5.21  #define DPRINTF(_f, _a...) ((void)0)
    5.22  #endif
    5.23  
    5.24 -#if DDEBUG
    5.25 -#define DDPRINTF(_f, _a...) printf ( _f , ## _a )
    5.26 +#define PROGRESS 0
    5.27 +#if PROGRESS
    5.28 +#define PPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
    5.29  #else
    5.30 -#define DDPRINTF(_f, _a...) ((void)0)
    5.31 +#define PPRINTF(_f, _a...)
    5.32  #endif
    5.33  
    5.34  /*
    5.35 @@ -144,7 +150,7 @@ static long long tv_delta( struct timeva
    5.36  }
    5.37  
    5.38  
    5.39 -#define START_MBIT_RATE ioctxt->resource
    5.40 +#define START_MBIT_RATE 0 //ioctxt->resource
    5.41  
    5.42  static int mbit_rate, ombit_rate = 0;
    5.43  static int burst_time_us = -1;
    5.44 @@ -167,7 +173,8 @@ static int burst_time_us = -1;
    5.45  #define RATE_TO_BTU 781250
    5.46  #define BURST_TIME_US burst_time_us
    5.47  
    5.48 -static int xcio_ratewrite(XcIOContext *ioctxt, void *buf, int n)
    5.49 +static int
    5.50 +ratewrite(int io_fd, void *buf, int n)
    5.51  {
    5.52      static int budget = 0;
    5.53      static struct timeval last_put = { 0 };
    5.54 @@ -176,16 +183,15 @@ static int xcio_ratewrite(XcIOContext *i
    5.55      long long delta;
    5.56  
    5.57      if (START_MBIT_RATE == 0)
    5.58 -	return xcio_write(ioctxt, buf, n);
    5.59 +	return write(io_fd, buf, n);
    5.60      
    5.61      budget -= n;
    5.62      if (budget < 0) {
    5.63  	if (MBIT_RATE != ombit_rate) {
    5.64  	    BURST_TIME_US = RATE_TO_BTU / MBIT_RATE;
    5.65  	    ombit_rate = MBIT_RATE;
    5.66 -	    xcio_info(ioctxt,
    5.67 -		      "rate limit: %d mbit/s burst budget %d slot time %d\n",
    5.68 -		      MBIT_RATE, BURST_BUDGET, BURST_TIME_US);
    5.69 +	    DPRINTF("rate limit: %d mbit/s burst budget %d slot time %d\n",
    5.70 +		    MBIT_RATE, BURST_BUDGET, BURST_TIME_US);
    5.71  	}
    5.72  	if (last_put.tv_sec == 0) {
    5.73  	    budget += BURST_BUDGET;
    5.74 @@ -213,7 +219,7 @@ static int xcio_ratewrite(XcIOContext *i
    5.75  	    }
    5.76  	}
    5.77      }
    5.78 -    return xcio_write(ioctxt, buf, n);
    5.79 +    return write(io_fd, buf, n);
    5.80  }
    5.81  
    5.82  static int print_stats( int xc_handle, u32 domid, 
    5.83 @@ -235,7 +241,7 @@ static int print_stats( int xc_handle, u
    5.84      d1_cpu_now = xc_domain_get_cpu_usage(xc_handle, domid, /* FIXME */ 0)/1000;
    5.85  
    5.86      if ( (d0_cpu_now == -1) || (d1_cpu_now == -1) ) 
    5.87 -        printf("ARRHHH!!\n");
    5.88 +        fprintf(stderr, "ARRHHH!!\n");
    5.89  
    5.90      wall_delta = tv_delta(&wall_now,&wall_last)/1000;
    5.91  
    5.92 @@ -245,14 +251,15 @@ static int print_stats( int xc_handle, u
    5.93      d1_cpu_delta  = (d1_cpu_now - d1_cpu_last)/1000;
    5.94  
    5.95      if ( print )
    5.96 -        printf("delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
    5.97 -               "dirtied %dMb/s %" PRId32 " pages\n",
    5.98 -               wall_delta, 
    5.99 -               (int)((d0_cpu_delta*100)/wall_delta),
   5.100 -               (int)((d1_cpu_delta*100)/wall_delta),
   5.101 -               (int)((pages_sent*PAGE_SIZE)/(wall_delta*(1000/8))),
   5.102 -               (int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))),
   5.103 -               stats->dirty_count);
   5.104 +        fprintf(stderr,
   5.105 +		"delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
   5.106 +		"dirtied %dMb/s %" PRId32 " pages\n",
   5.107 +		wall_delta, 
   5.108 +		(int)((d0_cpu_delta*100)/wall_delta),
   5.109 +		(int)((d1_cpu_delta*100)/wall_delta),
   5.110 +		(int)((pages_sent*PAGE_SIZE)/(wall_delta*(1000/8))),
   5.111 +		(int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))),
   5.112 +		stats->dirty_count);
   5.113  
   5.114      if (((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))) > mbit_rate) {
   5.115  	mbit_rate = (int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8)))
   5.116 @@ -268,24 +275,6 @@ static int print_stats( int xc_handle, u
   5.117      return 0;
   5.118  }
   5.119  
   5.120 -/** Write the vmconfig string.
   5.121 - * It is stored as a 4-byte count 'n' followed by n bytes.
   5.122 - *
   5.123 - * @param ioctxt i/o context
   5.124 - * @return 0 on success, non-zero on error.
   5.125 - */
   5.126 -static int write_vmconfig(XcIOContext *ioctxt)
   5.127 -{
   5.128 -    int err = -1;
   5.129 -    if(xcio_write(ioctxt, &ioctxt->vmconfig_n, sizeof(ioctxt->vmconfig_n))) 
   5.130 -        goto exit;
   5.131 -    if(xcio_write(ioctxt, ioctxt->vmconfig, ioctxt->vmconfig_n)) 
   5.132 -        goto exit;
   5.133 -    err = 0;
   5.134 -  exit:
   5.135 -    return err;
   5.136 -}
   5.137 -
   5.138  static int analysis_phase( int xc_handle, u32 domid, 
   5.139                             int nr_pfns, unsigned long *arr, int runs )
   5.140  {
   5.141 @@ -302,7 +291,7 @@ static int analysis_phase( int xc_handle
   5.142          xc_shadow_control( xc_handle, domid, 
   5.143                             DOM0_SHADOW_CONTROL_OP_CLEAN,
   5.144                             arr, nr_pfns, NULL);
   5.145 -        printf("#Flush\n");
   5.146 +        fprintf(stderr, "#Flush\n");
   5.147          for ( i = 0; i < 40; i++ )
   5.148          {     
   5.149              usleep(50000);     
   5.150 @@ -311,11 +300,11 @@ static int analysis_phase( int xc_handle
   5.151                                 DOM0_SHADOW_CONTROL_OP_PEEK,
   5.152                                 NULL, 0, &stats);
   5.153  
   5.154 -            printf("now= %lld faults= %" PRId32 " dirty= %" PRId32
   5.155 -                   " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n", 
   5.156 -                   ((now-start)+500)/1000, 
   5.157 -                   stats.fault_count, stats.dirty_count,
   5.158 -                   stats.dirty_net_count, stats.dirty_block_count);
   5.159 +            fprintf(stderr, "now= %lld faults= %" PRId32 " dirty= %" PRId32
   5.160 +		    " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n", 
   5.161 +		    ((now-start)+500)/1000, 
   5.162 +		    stats.fault_count, stats.dirty_count,
   5.163 +		    stats.dirty_net_count, stats.dirty_block_count);
   5.164          }
   5.165      }
   5.166  
   5.167 @@ -323,26 +312,36 @@ static int analysis_phase( int xc_handle
   5.168  }
   5.169  
   5.170  
   5.171 -int suspend_and_state(int xc_handle, XcIOContext *ioctxt,		      
   5.172 +int suspend_and_state(int xc_handle, int io_fd,	int dom,	      
   5.173                        xc_dominfo_t *info,
   5.174                        vcpu_guest_context_t *ctxt)
   5.175  {
   5.176      int i=0;
   5.177 -    
   5.178 -    xcio_suspend_domain(ioctxt);
   5.179 +    char ans[30];
   5.180 +
   5.181 +    printf("suspend\n");
   5.182 +    fflush(stdout);
   5.183 +    if (fgets(ans, sizeof(ans), stdin) == NULL) {
   5.184 +	ERR("failed reading suspend reply");
   5.185 +	return -1;
   5.186 +    }
   5.187 +    if (strncmp(ans, "done\n", 5)) {
   5.188 +	ERR("suspend reply incorrect: %s", ans);
   5.189 +	return -1;
   5.190 +    }
   5.191  
   5.192  retry:
   5.193  
   5.194 -    if ( xc_domain_getinfo(xc_handle, ioctxt->domain, 1, info) != 1)
   5.195 +    if ( xc_domain_getinfo(xc_handle, dom, 1, info) != 1)
   5.196      {
   5.197 -	xcio_error(ioctxt, "Could not get domain info");
   5.198 +	ERR("Could not get domain info");
   5.199  	return -1;
   5.200      }
   5.201  
   5.202 -    if ( xc_domain_get_vcpu_context(xc_handle, ioctxt->domain, 0 /* XXX */, 
   5.203 +    if ( xc_domain_get_vcpu_context(xc_handle, dom, 0 /* XXX */, 
   5.204  				    ctxt) )
   5.205      {
   5.206 -        xcio_error(ioctxt, "Could not get vcpu context");
   5.207 +        ERR("Could not get vcpu context");
   5.208      }
   5.209  
   5.210      if ( info->shutdown && info->shutdown_reason == SHUTDOWN_suspend )
   5.211 @@ -353,9 +352,9 @@ retry:
   5.212      if ( info->paused )
   5.213      {
   5.214  	// try unpausing domain, wait, and retest	
   5.215 -	xc_domain_unpause( xc_handle, ioctxt->domain );
   5.216 +	xc_domain_unpause( xc_handle, dom );
   5.217  
   5.218 -	xcio_error(ioctxt, "Domain was paused. Wait and re-test.");
   5.219 +	ERR("Domain was paused. Wait and re-test.");
   5.220  	usleep(10000);  // 10ms
   5.221  
   5.222  	goto retry;
   5.223 @@ -364,25 +363,24 @@ retry:
   5.224  
   5.225      if( ++i < 100 )
   5.226      {
   5.227 -	xcio_error(ioctxt, "Retry suspend domain.");
   5.228 +	ERR("Retry suspend domain.");
   5.229  	usleep(10000);  // 10ms	
   5.230  	goto retry;
   5.231      }
   5.232  
   5.233 -    xcio_error(ioctxt, "Unable to suspend domain.");
   5.234 +    ERR("Unable to suspend domain.");
   5.235  
   5.236      return -1;
   5.237  }
   5.238  
   5.239 -int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
   5.240 +int xc_linux_save(int xc_handle, int io_fd, u32 dom)
   5.241  {
   5.242      xc_dominfo_t info;
   5.243  
   5.244      int rc = 1, i, j, k, last_iter, iter = 0;
   5.245      unsigned long mfn;
   5.246 -    u32 domid = ioctxt->domain;
   5.247 -    int live =  (ioctxt->flags & XCFLAGS_LIVE);
   5.248 -    int debug = (ioctxt->flags & XCFLAGS_DEBUG);
   5.249 +    int live =  0; // (ioctxt->flags & XCFLAGS_LIVE);
   5.250 +    int debug = 0; // (ioctxt->flags & XCFLAGS_DEBUG);
   5.251      int sent_last_iter, skip_this_iter;
   5.252  
   5.253      /* Important tuning parameters */
   5.254 @@ -440,29 +438,29 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.255  
   5.256      MBIT_RATE = START_MBIT_RATE;
   5.257  
   5.258 -    xcio_info(ioctxt, "xc_linux_save start %d\n", domid);
   5.259 +    DPRINTF("xc_linux_save start %d\n", dom);
   5.260      
   5.261      if (mlock(&ctxt, sizeof(ctxt))) {
   5.262 -        xcio_perror(ioctxt, "Unable to mlock ctxt");
   5.263 +        ERR("Unable to mlock ctxt");
   5.264          return 1;
   5.265      }
   5.266      
   5.267 -    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1)
   5.268 +    if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1)
   5.269      {
   5.270 -        xcio_error(ioctxt, "Could not get domain info");
   5.271 +        ERR("Could not get domain info");
   5.272          goto out;
   5.273      }
   5.274 -    if ( xc_domain_get_vcpu_context( xc_handle, domid, /* FIXME */ 0, 
   5.275 +    if ( xc_domain_get_vcpu_context( xc_handle, dom, /* FIXME */ 0, 
   5.276                                  &ctxt) )
   5.277      {
   5.278 -        xcio_error(ioctxt, "Could not get vcpu context");
   5.279 +        ERR("Could not get vcpu context");
   5.280          goto out;
   5.281      }
   5.282      shared_info_frame = info.shared_info_frame;
   5.283  
   5.284      /* A cheesy test to see whether the domain contains valid state. */
   5.285      if ( ctxt.pt_base == 0 ){
   5.286 -        xcio_error(ioctxt, "Domain is not in a valid Linux guest OS state");
   5.287 +        ERR("Domain is not in a valid Linux guest OS state");
   5.288          goto out;
   5.289      }
   5.290      
   5.291 @@ -470,31 +468,29 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.292  
   5.293      /* cheesy sanity check */
   5.294      if ( nr_pfns > 1024*1024 ){
   5.295 -        xcio_error(ioctxt, 
   5.296 -                   "Invalid state record -- pfn count out of range: %lu", 
   5.297 -                   nr_pfns);
   5.298 +        ERR("Invalid state record -- pfn count out of range: %lu", nr_pfns);
   5.299          goto out;
   5.300      }
   5.301  
   5.302  
   5.303      /* Map the shared info frame */
   5.304 -    live_shinfo = xc_map_foreign_range(xc_handle, domid,
   5.305 +    live_shinfo = xc_map_foreign_range(xc_handle, dom,
   5.306                                          PAGE_SIZE, PROT_READ,
   5.307                                          shared_info_frame);
   5.308  
   5.309      if (!live_shinfo){
   5.310 -        xcio_error(ioctxt, "Couldn't map live_shinfo");
   5.311 +        ERR("Couldn't map live_shinfo");
   5.312          goto out;
   5.313      }
   5.314  
   5.315      /* the pfn_to_mfn_frame_list fits in a single page */
   5.316      live_pfn_to_mfn_frame_list = 
   5.317 -        xc_map_foreign_range(xc_handle, domid, 
   5.318 +        xc_map_foreign_range(xc_handle, dom, 
   5.319                                PAGE_SIZE, PROT_READ, 
   5.320                                live_shinfo->arch.pfn_to_mfn_frame_list );
   5.321  
   5.322      if (!live_pfn_to_mfn_frame_list){
   5.323 -        xcio_error(ioctxt, "Couldn't map pfn_to_mfn_frame_list");
   5.324 +        ERR("Couldn't map pfn_to_mfn_frame_list");
   5.325          goto out;
   5.326      }
   5.327  
   5.328 @@ -504,12 +500,12 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.329         (its not clear why it would want to change them, and we'll be OK
   5.330         from a safety POV anyhow. */
   5.331  
   5.332 -    live_pfn_to_mfn_table = xc_map_foreign_batch(xc_handle, domid, 
   5.333 +    live_pfn_to_mfn_table = xc_map_foreign_batch(xc_handle, dom, 
   5.334                                                   PROT_READ,
   5.335                                                   live_pfn_to_mfn_frame_list,
   5.336                                                   (nr_pfns+1023)/1024 );  
   5.337      if( !live_pfn_to_mfn_table ){
   5.338 -        xcio_perror(ioctxt, "Couldn't map pfn_to_mfn table");
   5.339 +        ERR("Couldn't map pfn_to_mfn table");
   5.340          goto out;
   5.341      }
   5.342  
   5.343 @@ -526,8 +522,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.344  
   5.345      for ( i = 0; i < nr_pfns; i += 1024 ){
   5.346          if ( !translate_mfn_to_pfn(&pfn_to_mfn_frame_list[i/1024]) ){
   5.347 -            xcio_error(ioctxt, 
   5.348 -                       "Frame# in pfn-to-mfn frame list is not in pseudophys");
   5.349 +            ERR("Frame# in pfn-to-mfn frame list is not in pseudophys");
   5.350              goto out;
   5.351          }
   5.352      }
   5.353 @@ -537,10 +532,10 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.354  
   5.355      if( live )
   5.356      {
   5.357 -        if ( xc_shadow_control( xc_handle, domid, 
   5.358 +        if ( xc_shadow_control( xc_handle, dom, 
   5.359                                  DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY,
   5.360                                  NULL, 0, NULL ) < 0 ) {
   5.361 -            xcio_error(ioctxt, "Couldn't enable shadow mode");
   5.362 +            ERR("Couldn't enable shadow mode");
   5.363              goto out;
   5.364          }
   5.365  
   5.366 @@ -551,9 +546,9 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.367  
   5.368          last_iter = 1;
   5.369  
   5.370 -	if ( suspend_and_state( xc_handle, ioctxt, &info, &ctxt) )
   5.371 +	if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
   5.372  	{
   5.373 -	    xcio_error(ioctxt, "Domain appears not to have suspended");
   5.374 +	    ERR("Domain appears not to have suspended");
   5.375  	    goto out;
   5.376  	}
   5.377  
   5.378 @@ -577,27 +572,27 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.379          to_skip = malloc( sz );
   5.380  
   5.381          if (!to_send || !to_fix || !to_skip){
   5.382 -            xcio_error(ioctxt, "Couldn't allocate to_send array");
   5.383 +            ERR("Couldn't allocate to_send array");
   5.384              goto out;
   5.385          }
   5.386  
   5.387          memset( to_send, 0xff, sz );
   5.388  
   5.389          if ( mlock( to_send, sz ) ){
   5.390 -            xcio_perror(ioctxt, "Unable to mlock to_send");
   5.391 +            ERR("Unable to mlock to_send");
   5.392              return 1;
   5.393          }
   5.394  
   5.395          /* (to fix is local only) */
   5.396  
   5.397          if ( mlock( to_skip, sz ) ){
   5.398 -            xcio_perror(ioctxt, "Unable to mlock to_skip");
   5.399 +            ERR("Unable to mlock to_skip");
   5.400              return 1;
   5.401          }
   5.402  
   5.403      }
   5.404  
   5.405 -    analysis_phase( xc_handle, domid, nr_pfns, to_skip, 0 );
   5.406 +    analysis_phase( xc_handle, dom, nr_pfns, to_skip, 0 );
   5.407  
   5.408      /* We want zeroed memory so use calloc rather than malloc. */
   5.409      pfn_type = calloc(BATCH_SIZE, sizeof(unsigned long));
   5.410 @@ -609,7 +604,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.411      }
   5.412  
   5.413      if ( mlock( pfn_type, BATCH_SIZE * sizeof(unsigned long) ) ){
   5.414 -        xcio_error(ioctxt, "Unable to mlock");
   5.415 +        ERR("Unable to mlock");
   5.416          goto out;
   5.417      }
   5.418  
   5.419 @@ -626,33 +621,29 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.420  	    
   5.421  	    if( (live_mfn_to_pfn_table[mfn] != i) && (mfn != 0xffffffffUL) )
   5.422  	    {
   5.423 -		printf("i=0x%x mfn=%lx live_mfn_to_pfn_table=%lx\n",
   5.424 -		       i,mfn,live_mfn_to_pfn_table[mfn]);
   5.425 +		fprintf(stderr, "i=0x%x mfn=%lx live_mfn_to_pfn_table=%lx\n",
   5.426 +			i,mfn,live_mfn_to_pfn_table[mfn]);
   5.427  		err++;
   5.428  	    }
   5.429  	}
   5.430 -	printf("Had %d unexplained entries in p2m table\n",err);
   5.431 +	fprintf(stderr, "Had %d unexplained entries in p2m table\n",err);
   5.432      }
   5.433  #endif
   5.434  
   5.435  
   5.436      /* Start writing out the saved-domain record. */
   5.437  
   5.438 -    if ( xcio_write(ioctxt, "LinuxGuestRecord",    16) ){
   5.439 -        xcio_error(ioctxt, "Error writing header");
   5.440 -        goto out;
   5.441 +    if (write(io_fd, &nr_pfns, sizeof(unsigned long)) !=
   5.442 +	sizeof(unsigned long)) {
   5.443 +	ERR("write: nr_pfns");
   5.444 +	goto out;
   5.445      }
   5.446 -    if(write_vmconfig(ioctxt)){
   5.447 -        xcio_error(ioctxt, "Error writing vmconfig");
   5.448 -        goto out;
   5.449 -    }
   5.450 -    if ( xcio_write(ioctxt, &nr_pfns,              sizeof(unsigned long)) ||
   5.451 -         xcio_write(ioctxt, pfn_to_mfn_frame_list, PAGE_SIZE) ){
   5.452 -        xcio_error(ioctxt, "Error writing header");
   5.453 +    if (write(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE) {
   5.454 +        ERR("write: pfn_to_mfn_frame_list");
   5.455          goto out;
   5.456      }
   5.457  
   5.458 -    print_stats( xc_handle, domid, 0, &stats, 0 );
   5.459 +    print_stats( xc_handle, dom, 0, &stats, 0 );
   5.460  
   5.461      /* Now write out each data page, canonicalising page tables as we go... */
   5.462      
   5.463 @@ -665,13 +656,13 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.464          prev_pc = 0;
   5.465          N=0;
   5.466  
   5.467 -        xcio_info(ioctxt, "Saving memory pages: iter %d   0%%", iter);
   5.468 +        DPRINTF("Saving memory pages: iter %d   0%%", iter);
   5.469  
   5.470          while( N < nr_pfns ){
   5.471              unsigned int this_pc = (N * 100) / nr_pfns;
   5.472  
   5.473              if ( (this_pc - prev_pc) >= 5 ){
   5.474 -                xcio_info(ioctxt, "\b\b\b\b%3d%%", this_pc);
   5.475 +                DPRINTF("\b\b\b\b%3d%%", this_pc);
   5.476                  prev_pc = this_pc;
   5.477              }
   5.478  
   5.479 @@ -679,11 +670,11 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.480                 but this is fast enough for the moment. */
   5.481  
   5.482              if ( !last_iter && 
   5.483 -		 xc_shadow_control(xc_handle, domid, 
   5.484 +		 xc_shadow_control(xc_handle, dom, 
   5.485                                     DOM0_SHADOW_CONTROL_OP_PEEK,
   5.486                                     to_skip, nr_pfns, NULL) != nr_pfns )
   5.487  	    {
   5.488 -                xcio_error(ioctxt, "Error peeking shadow bitmap");
   5.489 +                ERR("Error peeking shadow bitmap");
   5.490                  goto out;
   5.491              }
   5.492       
   5.493 @@ -733,8 +724,8 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.494  
   5.495                      set_bit( n, to_fix );
   5.496                      if( iter>1 )
   5.497 -                        DDPRINTF("netbuf race: iter %d, pfn %x. mfn %lx\n",
   5.498 -                                 iter,n,pfn_type[batch]);
   5.499 +                        DPRINTF("netbuf race: iter %d, pfn %x. mfn %lx\n",
   5.500 +				iter,n,pfn_type[batch]);
   5.501                      continue;
   5.502                  }
   5.503  
   5.504 @@ -752,27 +743,27 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.505                  batch++;
   5.506              }
   5.507       
   5.508 -//            DDPRINTF("batch %d:%d (n=%d)\n", iter, batch, n);
   5.509 +//            DPRINTF("batch %d:%d (n=%d)\n", iter, batch, n);
   5.510  
   5.511              if ( batch == 0 )
   5.512                  goto skip; /* vanishingly unlikely... */
   5.513        
   5.514 -            if ( (region_base = xc_map_foreign_batch(xc_handle, domid, 
   5.515 +            if ( (region_base = xc_map_foreign_batch(xc_handle, dom, 
   5.516                                                       PROT_READ,
   5.517                                                       pfn_type,
   5.518                                                       batch)) == 0 ){
   5.519 -                xcio_perror(ioctxt, "map batch failed");
   5.520 +                ERR("map batch failed");
   5.521                  goto out;
   5.522              }
   5.523       
   5.524 -            if ( get_pfn_type_batch(xc_handle, domid, batch, pfn_type) ){
   5.525 -                xcio_error(ioctxt, "get_pfn_type_batch failed");
   5.526 +            if ( get_pfn_type_batch(xc_handle, dom, batch, pfn_type) ){
   5.527 +                ERR("get_pfn_type_batch failed");
   5.528                  goto out;
   5.529              }
   5.530       
   5.531              for ( j = 0; j < batch; j++ ){
   5.532                  if ( (pfn_type[j] & LTAB_MASK) == XTAB ){
   5.533 -                    DDPRINTF("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
   5.534 +                    DPRINTF("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
   5.535                      continue;
   5.536                  }
   5.537    
   5.538 @@ -789,13 +780,14 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.539                  pfn_type[j] = (pfn_type[j] & LTAB_MASK) | pfn_batch[j];
   5.540              }
   5.541  
   5.542 -            if ( xcio_write(ioctxt, &batch, sizeof(int) ) ){
   5.543 -                xcio_error(ioctxt, "Error when writing to state file (2)");
   5.544 +            if (write(io_fd, &batch, sizeof(int)) != sizeof(int)) {
   5.545 +                ERR("Error when writing to state file (2)");
   5.546                  goto out;
   5.547              }
   5.548  
   5.549 -            if ( xcio_write(ioctxt, pfn_type, sizeof(unsigned long)*j ) ){
   5.550 -                xcio_error(ioctxt, "Error when writing to state file (3)");
   5.551 +            if (write(io_fd, pfn_type, sizeof(unsigned long)*j) !=
   5.552 +		sizeof(unsigned long)*j) {
   5.553 +                ERR("Error when writing to state file (3)");
   5.554                  goto out;
   5.555              }
   5.556       
   5.557 @@ -803,7 +795,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.558              for( j = 0; j < batch; j++ ){
   5.559                  /* write out pages in batch */
   5.560                  if( (pfn_type[j] & LTAB_MASK) == XTAB){
   5.561 -                    DDPRINTF("SKIP BOGUS page %i mfn %08lx\n",j,pfn_type[j]);
   5.562 +                    DPRINTF("SKIP BOGUS page %i mfn %08lx\n",j,pfn_type[j]);
   5.563                      continue;
   5.564                  }
   5.565    
   5.566 @@ -827,14 +819,14 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.567                          if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
   5.568                          {
   5.569                              /* I don't think this should ever happen */
   5.570 -                            printf("FNI %d : [%08lx,%d] pte=%08lx, "
   5.571 -                                   "mfn=%08lx, pfn=%08lx [mfn]=%08lx\n",
   5.572 -                                   j, pfn_type[j], k,
   5.573 -                                   page[k], mfn, live_mfn_to_pfn_table[mfn],
   5.574 -                                   (live_mfn_to_pfn_table[mfn]<nr_pfns)? 
   5.575 -                                   live_pfn_to_mfn_table[
   5.576 -                                       live_mfn_to_pfn_table[mfn]] : 
   5.577 -                                   0xdeadbeef);
   5.578 +                            fprintf(stderr, "FNI %d : [%08lx,%d] pte=%08lx, "
   5.579 +				    "mfn=%08lx, pfn=%08lx [mfn]=%08lx\n",
   5.580 +				    j, pfn_type[j], k,
   5.581 +				    page[k], mfn, live_mfn_to_pfn_table[mfn],
   5.582 +				    (live_mfn_to_pfn_table[mfn]<nr_pfns)? 
   5.583 +				    live_pfn_to_mfn_table[
   5.584 +					live_mfn_to_pfn_table[mfn]] : 
   5.585 +				    0xdeadbeef);
   5.586  
   5.587                              pfn = 0; /* be suspicious */
   5.588                          }
   5.589 @@ -843,26 +835,25 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.590                          page[k] |= pfn << PAGE_SHIFT;
   5.591     
   5.592  #if 0
   5.593 -                        printf("L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx "
   5.594 -                               "xpfn=%d\n",
   5.595 -                               pfn_type[j]>>28,
   5.596 -                               j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
   5.597 +                        fprintf(stderr,
   5.598 +				"L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx "
   5.599 +				"xpfn=%d\n",
   5.600 +				pfn_type[j]>>28,
   5.601 +				j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
   5.602  #endif     
   5.603 -   
   5.604 +			
   5.605                      } /* end of page table rewrite for loop */
   5.606        
   5.607 -                    if ( xcio_ratewrite(ioctxt, page, PAGE_SIZE) ){
   5.608 -                        xcio_error(ioctxt, 
   5.609 -                                   "Error when writing to state file (4)");
   5.610 +                    if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
   5.611 +                        ERR("Error when writing to state file (4)");
   5.612                          goto out;
   5.613                      }
   5.614        
   5.615                  }  /* end of it's a PT page */ else {  /* normal page */
   5.616  
   5.617 -                    if ( xcio_ratewrite(ioctxt, region_base + (PAGE_SIZE*j), 
   5.618 -                                     PAGE_SIZE) ){
   5.619 -                        xcio_error(ioctxt, 
   5.620 -                                   "Error when writing to state file (5)");
   5.621 +                    if (ratewrite(io_fd, region_base + (PAGE_SIZE*j), 
   5.622 +				  PAGE_SIZE) != PAGE_SIZE) {
   5.623 +                        ERR("Error when writing to state file (5)");
   5.624                          goto out;
   5.625                      }
   5.626                  }
   5.627 @@ -878,27 +869,26 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.628  
   5.629          total_sent += sent_this_iter;
   5.630  
   5.631 -        xcio_info(ioctxt, "\r %d: sent %d, skipped %d, ", 
   5.632 +        DPRINTF("\r %d: sent %d, skipped %d, ", 
   5.633                         iter, sent_this_iter, skip_this_iter );
   5.634  
   5.635          if ( last_iter ) {
   5.636 -            print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
   5.637 +            print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
   5.638  
   5.639 -            xcio_info(ioctxt, "Total pages sent= %d (%.2fx)\n", 
   5.640 +            DPRINTF("Total pages sent= %d (%.2fx)\n", 
   5.641                             total_sent, ((float)total_sent)/nr_pfns );
   5.642 -            xcio_info(ioctxt, "(of which %d were fixups)\n", needed_to_fix  );
   5.643 +            DPRINTF("(of which %d were fixups)\n", needed_to_fix  );
   5.644          }       
   5.645  
   5.646          if (last_iter && debug){
   5.647              int minusone = -1;
   5.648              memset( to_send, 0xff, (nr_pfns+8)/8 );
   5.649              debug = 0;
   5.650 -            printf("Entering debug resend-all mode\n");
   5.651 +            fprintf(stderr, "Entering debug resend-all mode\n");
   5.652      
   5.653              /* send "-1" to put receiver into debug mode */
   5.654 -            if ( xcio_write(ioctxt, &minusone, sizeof(int)) )
   5.655 -            {
   5.656 -                xcio_error(ioctxt, "Error when writing to state file (6)");
   5.657 +            if (write(io_fd, &minusone, sizeof(int)) != sizeof(int)) {
   5.658 +                ERR("Error when writing to state file (6)");
   5.659                  goto out;
   5.660              }
   5.661  
   5.662 @@ -919,30 +909,28 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.663                  DPRINTF("Start last iteration\n");
   5.664                  last_iter = 1;
   5.665  
   5.666 -		if ( suspend_and_state( xc_handle, ioctxt, &info, &ctxt) )
   5.667 +		if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
   5.668  		{
   5.669 -		    xcio_error(ioctxt, 
   5.670 -                               "Domain appears not to have suspended");
   5.671 +		    ERR("Domain appears not to have suspended");
   5.672  		    goto out;
   5.673  		}
   5.674  
   5.675 -		xcio_info(ioctxt,
   5.676 -                          "SUSPEND shinfo %08lx eip %08u esi %08u\n",
   5.677 -                          info.shared_info_frame,
   5.678 -                          ctxt.user_regs.eip, ctxt.user_regs.esi );
   5.679 +		DPRINTF("SUSPEND shinfo %08lx eip %08u esi %08u\n",
   5.680 +			info.shared_info_frame,
   5.681 +			ctxt.user_regs.eip, ctxt.user_regs.esi);
   5.682              } 
   5.683  
   5.684 -            if ( xc_shadow_control( xc_handle, domid, 
   5.685 +            if ( xc_shadow_control( xc_handle, dom, 
   5.686                                      DOM0_SHADOW_CONTROL_OP_CLEAN,
   5.687                                      to_send, nr_pfns, &stats ) != nr_pfns ) 
   5.688              {
   5.689 -                xcio_error(ioctxt, "Error flushing shadow PT");
   5.690 +                ERR("Error flushing shadow PT");
   5.691                  goto out;
   5.692              }
   5.693  
   5.694              sent_last_iter = sent_this_iter;
   5.695  
   5.696 -            print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
   5.697 +            print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
   5.698       
   5.699          }
   5.700  
   5.701 @@ -955,9 +943,8 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.702      rc = 0;
   5.703      
   5.704      /* Zero terminate */
   5.705 -    if ( xcio_write(ioctxt, &rc, sizeof(int)) )
   5.706 -    {
   5.707 -        xcio_error(ioctxt, "Error when writing to state file (6)");
   5.708 +    if (write(io_fd, &rc, sizeof(int)) != sizeof(int)) {
   5.709 +        ERR("Error when writing to state file (6)");
   5.710          goto out;
   5.711      }
   5.712  
   5.713 @@ -972,9 +959,8 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.714  		j++;
   5.715  	}
   5.716  
   5.717 -	if ( xcio_write(ioctxt, &j, sizeof(unsigned int)) )
   5.718 -	{
   5.719 -	    xcio_error(ioctxt, "Error when writing to state file (6a)");
   5.720 +	if (write(io_fd, &j, sizeof(unsigned int)) != sizeof(unsigned int)) {
   5.721 +	    ERR("Error when writing to state file (6a)");
   5.722  	    goto out;
   5.723  	}	
   5.724  
   5.725 @@ -987,10 +973,9 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.726  	    i++;
   5.727  	    if ( j == 1024 || i == nr_pfns )
   5.728  	    {
   5.729 -		if ( xcio_write(ioctxt, &pfntab, sizeof(unsigned long)*j) )
   5.730 -		{
   5.731 -		    xcio_error(ioctxt, 
   5.732 -                               "Error when writing to state file (6b)");
   5.733 +		if (write(io_fd, &pfntab, sizeof(unsigned long)*j) !=
   5.734 +		    sizeof(unsigned long)*j) {
   5.735 +		    ERR("Error when writing to state file (6b)");
   5.736  		    goto out;
   5.737  		}	
   5.738  		j = 0;
   5.739 @@ -999,47 +984,47 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.740      }
   5.741  
   5.742      /* Map the suspend-record MFN to pin it. The page must be owned by 
   5.743 -       domid for this to succeed. */
   5.744 -    p_srec = xc_map_foreign_range(xc_handle, domid,
   5.745 +       dom for this to succeed. */
   5.746 +    p_srec = xc_map_foreign_range(xc_handle, dom,
   5.747                                     sizeof(*p_srec), PROT_READ, 
   5.748                                     ctxt.user_regs.esi);
   5.749      if (!p_srec){
   5.750 -        xcio_error(ioctxt, "Couldn't map suspend record");
   5.751 +        ERR("Couldn't map suspend record");
   5.752          goto out;
   5.753      }
   5.754  
   5.755      if (nr_pfns != p_srec->nr_pfns )
   5.756      {
   5.757 -	xcio_error(ioctxt, "Suspend record nr_pfns unexpected (%ld != %ld)",
   5.758 +	ERR("Suspend record nr_pfns unexpected (%ld != %ld)",
   5.759  		   p_srec->nr_pfns, nr_pfns);
   5.760          goto out;
   5.761      }
   5.762  
   5.763      /* Canonicalise the suspend-record frame number. */
   5.764      if ( !translate_mfn_to_pfn(&ctxt.user_regs.esi) ){
   5.765 -        xcio_error(ioctxt, "Suspend record is not in range of pseudophys map");
   5.766 +        ERR("Suspend record is not in range of pseudophys map");
   5.767          goto out;
   5.768      }
   5.769  
   5.770      /* Canonicalise each GDT frame number. */
   5.771      for ( i = 0; i < ctxt.gdt_ents; i += 512 ) {
   5.772          if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) {
   5.773 -            xcio_error(ioctxt, "GDT frame is not in range of pseudophys map");
   5.774 +            ERR("GDT frame is not in range of pseudophys map");
   5.775              goto out;
   5.776          }
   5.777      }
   5.778  
   5.779      /* Canonicalise the page table base pointer. */
   5.780      if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.pt_base >> PAGE_SHIFT) ) {
   5.781 -        xcio_error(ioctxt, "PT base is not in range of pseudophys map");
   5.782 +        ERR("PT base is not in range of pseudophys map");
   5.783          goto out;
   5.784      }
   5.785      ctxt.pt_base = live_mfn_to_pfn_table[ctxt.pt_base >> PAGE_SHIFT] <<
   5.786          PAGE_SHIFT;
   5.787  
   5.788 -    if ( xcio_write(ioctxt, &ctxt,       sizeof(ctxt)) ||
   5.789 -         xcio_write(ioctxt, live_shinfo, PAGE_SIZE) ) {
   5.790 -        xcio_error(ioctxt, "Error when writing to state file (1)");
   5.791 +    if (write(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
   5.792 +	write(io_fd, live_shinfo, PAGE_SIZE) != PAGE_SIZE) {
   5.793 +        ERR("Error when writing to state file (1)");
   5.794          goto out;
   5.795      }
   5.796  
     6.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue May 24 09:42:24 2005 +0000
     6.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue May 24 17:47:14 2005 +0000
     6.3 @@ -254,93 +254,6 @@ static PyObject *pyxc_domain_getinfo(PyO
     6.4      return list;
     6.5  }
     6.6  
     6.7 -static int file_save(XcObject *xc, XcIOContext *ctxt, char *state_file)
     6.8 -{
     6.9 -    int rc = -1;
    6.10 -    int fd = -1;
    6.11 -    int open_flags = (O_CREAT | O_EXCL | O_WRONLY);
    6.12 -    int open_mode = 0644;
    6.13 -
    6.14 -    printf("%s>\n", __FUNCTION__);
    6.15 -
    6.16 -    if ( (fd = open(state_file, open_flags, open_mode)) < 0 )
    6.17 -    {
    6.18 -        xcio_perror(ctxt, "Could not open file for writing");
    6.19 -        goto exit;
    6.20 -    }
    6.21 -
    6.22 -    printf("%s>gzip_stream_fdopen... \n", __FUNCTION__);
    6.23 -
    6.24 -    /* Compression rate 1: we want speed over compression. 
    6.25 -     * We're mainly going for those zero pages, after all.
    6.26 -     */
    6.27 -    ctxt->io = gzip_stream_fdopen(fd, "wb1");
    6.28 -    if ( ctxt->io == NULL )
    6.29 -    {
    6.30 -        xcio_perror(ctxt, "Could not allocate compression state");
    6.31 -        goto exit;
    6.32 -    }
    6.33 -
    6.34 -    printf("%s> xc_linux_save...\n", __FUNCTION__);
    6.35 -
    6.36 -    rc = xc_linux_save(xc->xc_handle, ctxt);
    6.37 -
    6.38 -  exit:
    6.39 -    if ( ctxt->io != NULL )
    6.40 -        IOStream_close(ctxt->io);
    6.41 -    if ( fd >= 0 )
    6.42 -        close(fd);
    6.43 -    unlink(state_file);
    6.44 -    printf("%s> rc=%d\n", __FUNCTION__, rc);
    6.45 -    return rc;
    6.46 -}
    6.47 -
    6.48 -static PyObject *pyxc_linux_save(PyObject *self,
    6.49 -                                 PyObject *args,
    6.50 -                                 PyObject *kwds)
    6.51 -{
    6.52 -    XcObject *xc = (XcObject *)self;
    6.53 -
    6.54 -    char *state_file;
    6.55 -    int progress = 1, debug = 0;
    6.56 -    PyObject *val = NULL;
    6.57 -    int rc = -1;
    6.58 -    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
    6.59 -
    6.60 -    static char *kwd_list[] = { "dom", "state_file", "vmconfig", "progress", "debug", NULL };
    6.61 -
    6.62 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|sii", kwd_list, 
    6.63 -                                      &ioctxt.domain,
    6.64 -                                      &state_file,
    6.65 -                                      &ioctxt.vmconfig,
    6.66 -                                      &progress, 
    6.67 -                                      &debug) )
    6.68 -        goto exit;
    6.69 -
    6.70 -    ioctxt.vmconfig_n = (ioctxt.vmconfig ? strlen(ioctxt.vmconfig) : 0);
    6.71 -
    6.72 -    if ( progress )
    6.73 -        ioctxt.flags |= XCFLAGS_VERBOSE;
    6.74 -    if ( debug )
    6.75 -        ioctxt.flags |= XCFLAGS_DEBUG;
    6.76 -
    6.77 -    if ( (state_file == NULL) || (state_file[0] == '\0') )
    6.78 -        goto exit;
    6.79 -    
    6.80 -    rc = file_save(xc, &ioctxt, state_file);
    6.81 -    if ( rc != 0 )
    6.82 -    {
    6.83 -        PyErr_SetFromErrno(xc_error);
    6.84 -        goto exit;
    6.85 -    } 
    6.86 -
    6.87 -    Py_INCREF(zero);
    6.88 -    val = zero;
    6.89 -
    6.90 -  exit:
    6.91 -    return val;
    6.92 -}
    6.93 -
    6.94  static PyObject *pyxc_linux_build(PyObject *self,
    6.95                                    PyObject *args,
    6.96                                    PyObject *kwds)
    6.97 @@ -999,15 +912,6 @@ static PyMethodDef pyxc_methods[] = {
    6.98        "reason why it shut itself down.\n" 
    6.99        " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
   6.100  
   6.101 -    { "linux_save", 
   6.102 -      (PyCFunction)pyxc_linux_save, 
   6.103 -      METH_VARARGS | METH_KEYWORDS, "\n"
   6.104 -      "Save the CPU and memory state of a Linux guest OS.\n"
   6.105 -      " dom        [int]:    Identifier of domain to be saved.\n"
   6.106 -      " state_file [str]:    Name of state file. Must not currently exist.\n"
   6.107 -      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
   6.108 -      "Returns: [int] 0 on success; -1 on error.\n" },
   6.109 -
   6.110      { "linux_build", 
   6.111        (PyCFunction)pyxc_linux_build, 
   6.112        METH_VARARGS | METH_KEYWORDS, "\n"
     7.1 --- a/tools/python/xen/util/xpopen.py	Tue May 24 09:42:24 2005 +0000
     7.2 +++ b/tools/python/xen/util/xpopen.py	Tue May 24 17:47:14 2005 +0000
     7.3 @@ -129,7 +129,7 @@ class xPopen3:
     7.4          try:
     7.5              os.execvp(cmd[0], cmd)
     7.6          finally:
     7.7 -            os._exit(1)
     7.8 +            os._exit(127)
     7.9  
    7.10      def poll(self):
    7.11          """Return the exit status of the child process if it has finished,
     8.1 --- a/tools/python/xen/xend/XendDomain.py	Tue May 24 09:42:24 2005 +0000
     8.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue May 24 17:47:14 2005 +0000
     8.3 @@ -90,7 +90,10 @@ class XendDomain:
     8.4          """Get info about a single domain from xc.
     8.5          Returns None if not found.
     8.6          """
     8.7 -        dom = int(dom)
     8.8 +        try:
     8.9 +            dom = int(dom)
    8.10 +        except ValueError:
    8.11 +            return None
    8.12          dominfo = xc.domain_getinfo(dom, 1)
    8.13          if dominfo == [] or dominfo[0]['dom'] != dom:
    8.14              dominfo = None
    8.15 @@ -198,6 +201,8 @@ class XendDomain:
    8.16                          log.debug('XendDomain>reap> Suspended domain died id=%s', id)
    8.17                      else:
    8.18                          eserver.inject('xend.domain.suspended', [name, id])
    8.19 +                        if dominfo:
    8.20 +                            dominfo.state_set("suspended")
    8.21                          continue
    8.22                  if reason in ['poweroff', 'reboot']:
    8.23                      eserver.inject('xend.domain.exit', [name, id, reason])
    8.24 @@ -349,7 +354,7 @@ class XendDomain:
    8.25  
    8.26              l = fd.read_exact(sizeof_int,
    8.27                                "not a valid guest state file: config size read")
    8.28 -            vmconfig_size = unpack("i", l)[0] # XXX endianess
    8.29 +            vmconfig_size = unpack("!i", l)[0]
    8.30              vmconfig_buf = fd.read_exact(vmconfig_size,
    8.31                  "not a valid guest state file: config read")
    8.32  
    8.33 @@ -384,17 +389,22 @@ class XendDomain:
    8.34              p.register(child.childerr.fileno())
    8.35              while True:
    8.36                  r = p.poll()
    8.37 -                for l in child.childerr.readlines():
    8.38 -                    log.error(l.rstrip())
    8.39 -                    lasterr = l.rstrip()
    8.40 -                for l in child.fromchild.readlines():
    8.41 -                    log.info(l.rstrip())
    8.42 +                for (fd, event) in r:
    8.43 +                    if not event & select.POLLIN:
    8.44 +                        continue
    8.45 +                    if fd == child.childerr.fileno():
    8.46 +                        l = child.childerr.readline()
    8.47 +                        log.error(l.rstrip())
    8.48 +                        lasterr = l.rstrip()
    8.49 +                    if fd == child.fromchild.fileno():
    8.50 +                        l = child.fromchild.readline()
    8.51 +                        log.info(l.rstrip())
    8.52                  if filter(lambda (fd, event): event & select.POLLHUP, r):
    8.53                      break
    8.54  
    8.55              if child.wait() != 0:
    8.56                  raise XendError("xc_restore failed: %s" % lasterr)
    8.57 -            
    8.58 +
    8.59              return dominfo
    8.60  
    8.61          except IOError, ex:
    8.62 @@ -592,10 +602,66 @@ class XendDomain:
    8.63          @param dst:      destination file
    8.64          @param progress: output progress if true
    8.65          """
    8.66 -        dominfo = self.domain_lookup(id)
    8.67 -        xmigrate = XendMigrate.instance()
    8.68 -        return xmigrate.save_begin(dominfo, dst)
    8.69 -    
    8.70 +
    8.71 +        SIGNATURE = "LinuxGuestRecord"
    8.72 +        sizeof_int = calcsize("i")
    8.73 +        PATH_XC_SAVE = "/usr/libexec/xen/xc_save"
    8.74 +
    8.75 +        try:
    8.76 +            dominfo = self.domain_lookup(id)
    8.77 +
    8.78 +            fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
    8.79 +
    8.80 +            if os.write(fd, SIGNATURE) != len(SIGNATURE):
    8.81 +                raise XendError("could not write guest state file: signature")
    8.82 +
    8.83 +            config = sxp.to_string(dominfo.sxpr())
    8.84 +            if os.write(fd, pack("!i", len(config))) != sizeof_int:
    8.85 +                raise XendError("could not write guest state file: config len")
    8.86 +            if os.write(fd, config) != len(config):
    8.87 +                raise XendError("could not write guest state file: config")
    8.88 +
    8.89 +            cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
    8.90 +                   dominfo.id]
    8.91 +            log.info("[xc_save] " + join(cmd))
    8.92 +            child = xPopen3(cmd, True, -1, [fd, xc.handle()])
    8.93 +            
    8.94 +            lasterr = ""
    8.95 +            p = select.poll()
    8.96 +            p.register(child.fromchild.fileno())
    8.97 +            p.register(child.childerr.fileno())
    8.98 +            while True:
    8.99 +                r = p.poll()
   8.100 +                for (fd, event) in r:
   8.101 +                    if not event & select.POLLIN:
   8.102 +                        continue
   8.103 +                    if fd == child.childerr.fileno():
   8.104 +                        l = child.childerr.readline()
   8.105 +                        log.error(l.rstrip())
   8.106 +                        lasterr = l.rstrip()
   8.107 +                    if fd == child.fromchild.fileno():
   8.108 +                        l = child.fromchild.readline()
   8.109 +                        if l.rstrip() == "suspend":
   8.110 +                            log.info("suspending %s" % dominfo.id)
   8.111 +                            self.domain_shutdown(dominfo.id, reason='suspend')
   8.112 +                            dominfo.state_wait("suspended")
   8.113 +                            log.info("suspend %s done" % dominfo.id)
   8.114 +                            child.tochild.write("done\n")
   8.115 +                            child.tochild.flush()
   8.116 +                if filter(lambda (fd, event): event & select.POLLHUP, r):
   8.117 +                    break
   8.118 +
   8.119 +            if child.wait() >> 8 == 127:
   8.120 +                lasterr = "popen %s failed" % PATH_XC_SAVE
   8.121 +            if child.wait() != 0:
   8.122 +                raise XendError("xc_save failed: %s" % lasterr)
   8.123 +
   8.124 +            self.domain_destroy(dominfo.id)
   8.125 +            return None
   8.126 +
   8.127 +        except:
   8.128 +            raise
   8.129 +
   8.130      def domain_pincpu(self, id, vcpu, cpumap):
   8.131          """Set which cpus vcpu can use
   8.132  
     9.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue May 24 09:42:24 2005 +0000
     9.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue May 24 17:47:14 2005 +0000
     9.3 @@ -11,6 +11,7 @@ Author: Mike Wray <mike.wray@hp.com>
     9.4  import string
     9.5  import os
     9.6  import time
     9.7 +import threading
     9.8  
     9.9  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    9.10  import xen.util.ip
    9.11 @@ -74,6 +75,7 @@ STATE_RESTART_BOOTING = 'booting'
    9.12  
    9.13  STATE_VM_OK         = "ok"
    9.14  STATE_VM_TERMINATED = "terminated"
    9.15 +STATE_VM_SUSPENDED  = "suspended"
    9.16  
    9.17  
    9.18  def domain_exists(name):
    9.19 @@ -288,6 +290,7 @@ class XendDomainInfo:
    9.20          self.netif_backend = False
    9.21          #todo: state: running, suspended
    9.22          self.state = STATE_VM_OK
    9.23 +        self.state_updated = threading.Condition()
    9.24          self.shutdown_pending = None
    9.25  
    9.26          #todo: set to migrate info if migrating
    9.27 @@ -328,6 +331,19 @@ class XendDomainInfo:
    9.28          self.info = info
    9.29          self.memory = self.info['mem_kb'] / 1024
    9.30  
    9.31 +    def state_set(self, state):
    9.32 +        self.state_updated.acquire()
    9.33 +        if self.state != state:
    9.34 +            self.state = state
    9.35 +            self.state_updated.notifyAll()
    9.36 +        self.state_updated.release()
    9.37 +
    9.38 +    def state_wait(self, state):
    9.39 +        self.state_updated.acquire()
    9.40 +        while self.state != state:
    9.41 +            self.state_updated.wait()
    9.42 +        self.state_updated.release()
    9.43 +
    9.44      def __str__(self):
    9.45          s = "domain"
    9.46          s += " id=" + self.id
    10.1 --- a/tools/xcutils/Makefile	Tue May 24 09:42:24 2005 +0000
    10.2 +++ b/tools/xcutils/Makefile	Tue May 24 17:47:14 2005 +0000
    10.3 @@ -28,9 +28,10 @@ CFLAGS += $(INCLUDES)
    10.4  CFLAGS += -Wp,-MD,.$(@F).d
    10.5  PROG_DEP = .*.d
    10.6  
    10.7 -PROGRAMS		= xc_restore
    10.8 +PROGRAMS		= xc_restore xc_save
    10.9  
   10.10  xc_restore_OBJS		= xc_restore.o
   10.11 +xc_save_OBJS		= xc_save.o
   10.12  
   10.13  LDLIBS			= -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil
   10.14  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/xcutils/xc_save.c	Tue May 24 17:47:14 2005 +0000
    11.3 @@ -0,0 +1,29 @@
    11.4 +/* 
    11.5 + * This file is subject to the terms and conditions of the GNU General
    11.6 + * Public License.  See the file "COPYING" in the main directory of
    11.7 + * this archive for more details.
    11.8 + *
    11.9 + * Copyright (C) 2005 by Christian Limpach
   11.10 + *
   11.11 + */
   11.12 +
   11.13 +#include <stdlib.h>
   11.14 +#include <stdio.h>
   11.15 +#include <err.h>
   11.16 +
   11.17 +#include <xc.h>
   11.18 +
   11.19 +int
   11.20 +main(int argc, char **argv)
   11.21 +{
   11.22 +    unsigned int xc_fd, io_fd, domid;
   11.23 +
   11.24 +    if (argc != 4)
   11.25 +	errx(1, "usage: %s xcfd iofd domid", argv[0]);
   11.26 +
   11.27 +    xc_fd = atoi(argv[1]);
   11.28 +    io_fd = atoi(argv[2]);
   11.29 +    domid = atoi(argv[3]);
   11.30 +
   11.31 +    return xc_linux_save(xc_fd, io_fd, domid);
   11.32 +}
    12.1 --- a/tools/xfrd/xen_domain.c	Tue May 24 09:42:24 2005 +0000
    12.2 +++ b/tools/xfrd/xen_domain.c	Tue May 24 17:47:14 2005 +0000
    12.3 @@ -61,6 +61,7 @@ int xen_domain_snd(Conn *xend, IOStream 
    12.4                     char *vmconfig, int vmconfig_n,
    12.5                     int live, int resource){
    12.6      int err = 0;
    12.7 +#if 0
    12.8      XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
    12.9      ioctxt->domain = dom;
   12.10      ioctxt->io = io;
   12.11 @@ -76,6 +77,7 @@ int xen_domain_snd(Conn *xend, IOStream 
   12.12      ioctxt->resource = resource;
   12.13      err = xc_linux_save(xcinit(), ioctxt);
   12.14      dprintf("< err=%d\n", err);
   12.15 +#endif
   12.16      return err;
   12.17  }
   12.18