debuggers.hg

changeset 21293:742311878ae5

xl: Move xl command implementation to a seperate file

Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 04 11:23:17 2010 +0100 (2010-05-04)
parents 3e5383b537c5
children 35da124fc66a
files tools/libxl/Makefile tools/libxl/xl.c tools/libxl/xl_cmdimpl.c tools/libxl/xl_cmdimpl.h
line diff
     1.1 --- a/tools/libxl/Makefile	Tue May 04 11:09:32 2010 +0100
     1.2 +++ b/tools/libxl/Makefile	Tue May 04 11:23:17 2010 +0100
     1.3 @@ -79,7 +79,10 @@ libxlutil.a: $(LIBXLU_OBJS)
     1.4  xl.o: xl.c
     1.5  	$(CC) $(CFLAGS) -c xl.c
     1.6  
     1.7 -$(CLIENTS): xl.o libxlutil.so libxenlight.so
     1.8 +xl_cmdimpl.o: xl_cmdimpl.c
     1.9 +	$(CC) $(CFLAGS) -c xl_cmdimpl.c
    1.10 +
    1.11 +$(CLIENTS): xl.o xl_cmdimpl.o libxlutil.so libxenlight.so
    1.12  	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
    1.13  
    1.14  .PHONY: install
     2.1 --- a/tools/libxl/xl.c	Tue May 04 11:09:32 2010 +0100
     2.2 +++ b/tools/libxl/xl.c	Tue May 04 11:23:17 2010 +0100
     2.3 @@ -17,74 +17,21 @@
     2.4  #include "libxl_osdeps.h"
     2.5  
     2.6  #include <stdio.h>
     2.7 -#include <assert.h>
     2.8  #include <stdlib.h>
     2.9  #include <string.h>
    2.10  #include <unistd.h>
    2.11  #include <sys/time.h> /* for time */
    2.12 -#include <getopt.h>
    2.13  #include <sys/types.h>
    2.14  #include <sys/stat.h>
    2.15  #include <fcntl.h>
    2.16 -#include <signal.h>
    2.17 -#include <sys/socket.h>
    2.18 -#include <sys/select.h>
    2.19 -#include <arpa/inet.h>
    2.20 -#include <sys/utsname.h> /* for utsname in xl info */
    2.21 -#include <xenctrl.h>
    2.22  #include <ctype.h>
    2.23  #include <inttypes.h>
    2.24  
    2.25  #include "libxl.h"
    2.26 -#include "libxl_utils.h"
    2.27 -#include "libxlutil.h"
    2.28 -
    2.29 -#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
    2.30 -
    2.31 -static int logfile = 2;
    2.32 -
    2.33 -/* every libxl action in xl uses this same libxl context */
    2.34 -static struct libxl_ctx ctx;
    2.35 -
    2.36 -/* when we operate on a domain, it is this one: */
    2.37 -static uint32_t domid;
    2.38 -static const char *common_domname;
    2.39 -
    2.40 -
    2.41 -static const char savefileheader_magic[32]=
    2.42 -    "Xen saved domain, xl format\n \0 \r";
    2.43 +#include "xl_cmdimpl.h"
    2.44  
    2.45 -static const char migrate_receiver_banner[]=
    2.46 -    "xl migration receiver ready, send binary domain data.\n";
    2.47 -static const char migrate_receiver_ready[]=
    2.48 -    "domain received, ready to unpause";
    2.49 -static const char migrate_permission_to_go[]=
    2.50 -    "domain is yours, you are cleared to unpause";
    2.51 -static const char migrate_report[]=
    2.52 -    "my copy unpause results are as follows";
    2.53 -  /* followed by one byte:
    2.54 -   *     0: everything went well, domain is running
    2.55 -   *            next thing is we all exit
    2.56 -   * non-0: things went badly
    2.57 -   *            next thing should be a migrate_permission_to_go
    2.58 -   *            from target to source
    2.59 -   */
    2.60 -
    2.61 -struct save_file_header {
    2.62 -    char magic[32]; /* savefileheader_magic */
    2.63 -    /* All uint32_ts are in domain's byte order. */
    2.64 -    uint32_t byteorder; /* SAVEFILE_BYTEORDER_VALUE */
    2.65 -    uint32_t mandatory_flags; /* unknown flags => reject restore */
    2.66 -    uint32_t optional_flags; /* unknown flags => reject restore */
    2.67 -    uint32_t optional_data_len; /* skip, or skip tail, if not understood */
    2.68 -};
    2.69 -
    2.70 -/* Optional data, in order:
    2.71 - *   4 bytes uint32_t  config file size
    2.72 - *   n bytes           config file in Unix text file format
    2.73 - */
    2.74 -
    2.75 -#define SAVEFILE_BYTEORDER_VALUE ((uint32_t)0x01020304UL)
    2.76 +extern struct libxl_ctx ctx;
    2.77 +extern int logfile;
    2.78  
    2.79  void log_callback(void *userdata, int loglevel, const char *file, int line, const char *func, char *s)
    2.80  {
    2.81 @@ -94,2781 +41,6 @@ void log_callback(void *userdata, int lo
    2.82      write(logfile, str, strlen(str));
    2.83  }
    2.84  
    2.85 -static int domain_qualifier_to_domid(const char *p, uint32_t *domid_r,
    2.86 -                                     int *was_name_r)
    2.87 -{
    2.88 -    int i, alldigit;
    2.89 -
    2.90 -    alldigit = 1;
    2.91 -    for (i = 0; p[i]; i++) {
    2.92 -        if (!isdigit((uint8_t)p[i])) {
    2.93 -            alldigit = 0;
    2.94 -            break;
    2.95 -        }
    2.96 -    }
    2.97 -
    2.98 -    if (i > 0 && alldigit) {
    2.99 -        *domid_r = strtoul(p, NULL, 10);
   2.100 -        if (was_name_r) *was_name_r = 0;
   2.101 -        return 0;
   2.102 -    } else {
   2.103 -        /* check here if it's a uuid and do proper conversion */
   2.104 -    }
   2.105 -    if (was_name_r) *was_name_r = 1;
   2.106 -    return libxl_name_to_domid(&ctx, p, domid_r);
   2.107 -}
   2.108 -
   2.109 -static void find_domain(const char *p)
   2.110 -{
   2.111 -    int rc, was_name;
   2.112 -
   2.113 -    rc = domain_qualifier_to_domid(p, &domid, &was_name);
   2.114 -    if (rc) {
   2.115 -        fprintf(stderr, "%s is an invalid domain identifier (rc=%d)\n", p, rc);
   2.116 -        exit(2);
   2.117 -    }
   2.118 -    common_domname = was_name ? p : 0;
   2.119 -}
   2.120 -
   2.121 -#define LOG(_f, _a...)   dolog(__FILE__, __LINE__, __func__, _f "\n", ##_a)
   2.122 -
   2.123 -void dolog(const char *file, int line, const char *func, char *fmt, ...)
   2.124 -{
   2.125 -    va_list ap;
   2.126 -    char *s;
   2.127 -    int rc;
   2.128 -
   2.129 -    va_start(ap, fmt);
   2.130 -    rc = vasprintf(&s, fmt, ap);
   2.131 -    va_end(ap);
   2.132 -    if (rc >= 0)
   2.133 -        write(logfile, s, rc);
   2.134 -}
   2.135 -
   2.136 -static void init_create_info(libxl_domain_create_info *c_info)
   2.137 -{
   2.138 -    memset(c_info, '\0', sizeof(*c_info));
   2.139 -    c_info->xsdata = NULL;
   2.140 -    c_info->platformdata = NULL;
   2.141 -    c_info->hvm = 1;
   2.142 -    c_info->oos = 1;
   2.143 -    c_info->ssidref = 0;
   2.144 -}
   2.145 -
   2.146 -static void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info)
   2.147 -{
   2.148 -    memset(b_info, '\0', sizeof(*b_info));
   2.149 -    b_info->timer_mode = -1;
   2.150 -    b_info->hpet = 1;
   2.151 -    b_info->vpt_align = -1;
   2.152 -    b_info->max_vcpus = 1;
   2.153 -    b_info->max_memkb = 32 * 1024;
   2.154 -    b_info->target_memkb = b_info->max_memkb;
   2.155 -    if (c_info->hvm) {
   2.156 -        b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus);
   2.157 -        b_info->video_memkb = 8 * 1024;
   2.158 -        b_info->kernel = "/usr/lib/xen/boot/hvmloader";
   2.159 -        b_info->hvm = 1;
   2.160 -        b_info->u.hvm.pae = 1;
   2.161 -        b_info->u.hvm.apic = 1;
   2.162 -        b_info->u.hvm.acpi = 1;
   2.163 -        b_info->u.hvm.nx = 1;
   2.164 -        b_info->u.hvm.viridian = 0;
   2.165 -    } else {
   2.166 -        b_info->u.pv.slack_memkb = 8 * 1024;
   2.167 -    }
   2.168 -}
   2.169 -
   2.170 -static void init_dm_info(libxl_device_model_info *dm_info,
   2.171 -        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
   2.172 -{
   2.173 -    int i;
   2.174 -    memset(dm_info, '\0', sizeof(*dm_info));
   2.175 -
   2.176 -    for (i = 0; i < 16; i++) {
   2.177 -        dm_info->uuid[i] = rand();
   2.178 -    }
   2.179 -
   2.180 -    dm_info->dom_name = c_info->name;
   2.181 -    dm_info->device_model = "/usr/lib/xen/bin/qemu-dm";
   2.182 -    dm_info->videoram = b_info->video_memkb / 1024;
   2.183 -    dm_info->apic = b_info->u.hvm.apic;
   2.184 -
   2.185 -    dm_info->stdvga = 0;
   2.186 -    dm_info->vnc = 1;
   2.187 -    dm_info->vnclisten = "127.0.0.1";
   2.188 -    dm_info->vncdisplay = 0;
   2.189 -    dm_info->vncunused = 0;
   2.190 -    dm_info->keymap = NULL;
   2.191 -    dm_info->sdl = 0;
   2.192 -    dm_info->opengl = 0;
   2.193 -    dm_info->nographic = 0;
   2.194 -    dm_info->serial = NULL;
   2.195 -    dm_info->boot = "cda";
   2.196 -    dm_info->usb = 0;
   2.197 -    dm_info->usbdevice = NULL;
   2.198 -}
   2.199 -
   2.200 -static void init_nic_info(libxl_device_nic *nic_info, int devnum)
   2.201 -{
   2.202 -    memset(nic_info, '\0', sizeof(*nic_info));
   2.203 -
   2.204 -    nic_info->backend_domid = 0;
   2.205 -    nic_info->domid = 0;
   2.206 -    nic_info->devid = devnum;
   2.207 -    nic_info->mtu = 1492;
   2.208 -    nic_info->model = "e1000";
   2.209 -    nic_info->mac[0] = 0x00;
   2.210 -    nic_info->mac[1] = 0x16;
   2.211 -    nic_info->mac[2] = 0x3e;
   2.212 -    nic_info->mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
   2.213 -    nic_info->mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
   2.214 -    nic_info->mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
   2.215 -    nic_info->ifname = NULL;
   2.216 -    nic_info->bridge = "xenbr0";
   2.217 -    nic_info->script = "/etc/xen/scripts/vif-bridge";
   2.218 -    nic_info->nictype = NICTYPE_IOEMU;
   2.219 -}
   2.220 -
   2.221 -static void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
   2.222 -{
   2.223 -    memset(vfb, 0x00, sizeof(libxl_device_vfb));
   2.224 -    vfb->devid = dev_num;
   2.225 -    vfb->vnc = 1;
   2.226 -    vfb->vnclisten = "127.0.0.1";
   2.227 -    vfb->vncdisplay = 0;
   2.228 -    vfb->vncunused = 1;
   2.229 -    vfb->keymap = NULL;
   2.230 -    vfb->sdl = 0;
   2.231 -    vfb->opengl = 0;
   2.232 -}
   2.233 -
   2.234 -static void init_vkb_info(libxl_device_vkb *vkb, int dev_num)
   2.235 -{
   2.236 -    memset(vkb, 0x00, sizeof(libxl_device_vkb));
   2.237 -    vkb->devid = dev_num;
   2.238 -}
   2.239 -
   2.240 -static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
   2.241 -{
   2.242 -    memset(console, 0x00, sizeof(libxl_device_console));
   2.243 -    console->devid = dev_num;
   2.244 -    console->constype = CONSTYPE_XENCONSOLED;
   2.245 -    if (state)
   2.246 -        console->build_state = state;
   2.247 -}
   2.248 -
   2.249 -static void printf_info(libxl_domain_create_info *c_info,
   2.250 -                        libxl_domain_build_info *b_info,
   2.251 -                        libxl_device_disk *disks,
   2.252 -                        int num_disks,
   2.253 -                        libxl_device_nic *vifs,
   2.254 -                        int num_vifs,
   2.255 -                        libxl_device_pci *pcidevs,
   2.256 -                        int num_pcidevs,
   2.257 -                        libxl_device_vfb *vfbs,
   2.258 -                        int num_vfbs,
   2.259 -                        libxl_device_vkb *vkb,
   2.260 -                        int num_vkbs,
   2.261 -                        libxl_device_model_info *dm_info)
   2.262 -{
   2.263 -    int i;
   2.264 -    printf("*** domain_create_info ***\n");
   2.265 -    printf("hvm: %d\n", c_info->hvm);
   2.266 -    printf("hap: %d\n", c_info->hap);
   2.267 -    printf("oos: %d\n", c_info->oos);
   2.268 -    printf("ssidref: %d\n", c_info->ssidref);
   2.269 -    printf("name: %s\n", c_info->name);
   2.270 -    printf("uuid: " UUID_FMT "\n",
   2.271 -           (c_info->uuid)[0], (c_info->uuid)[1], (c_info->uuid)[2], (c_info->uuid)[3],
   2.272 -           (c_info->uuid)[4], (c_info->uuid)[5], (c_info->uuid)[6], (c_info->uuid)[7],
   2.273 -           (c_info->uuid)[8], (c_info->uuid)[9], (c_info->uuid)[10], (c_info->uuid)[11],
   2.274 -           (c_info->uuid)[12], (c_info->uuid)[13], (c_info->uuid)[14], (c_info->uuid)[15]);
   2.275 -    if (c_info->xsdata)
   2.276 -        printf("xsdata: contains data\n");
   2.277 -    else
   2.278 -        printf("xsdata: (null)\n");
   2.279 -    if (c_info->platformdata)
   2.280 -        printf("platformdata: contains data\n");
   2.281 -    else
   2.282 -        printf("platformdata: (null)\n");
   2.283 -
   2.284 -
   2.285 -    printf("\n\n\n*** domain_build_info ***\n");
   2.286 -    printf("timer_mode: %d\n", b_info->timer_mode);
   2.287 -    printf("hpet: %d\n", b_info->hpet);
   2.288 -    printf("vpt_align: %d\n", b_info->vpt_align);
   2.289 -    printf("max_vcpus: %d\n", b_info->max_vcpus);
   2.290 -    printf("tsc_mode: %d\n", b_info->tsc_mode);
   2.291 -    printf("max_memkb: %d\n", b_info->max_memkb);
   2.292 -    printf("target_memkb: %d\n", b_info->target_memkb);
   2.293 -    printf("kernel: %s\n", b_info->kernel);
   2.294 -    printf("hvm: %d\n", b_info->hvm);
   2.295 -
   2.296 -    if (c_info->hvm) {
   2.297 -        printf("video_memkb: %d\n", b_info->video_memkb);
   2.298 -        printf("shadow_memkb: %d\n", b_info->shadow_memkb);
   2.299 -        printf("    pae: %d\n", b_info->u.hvm.pae);
   2.300 -        printf("    apic: %d\n", b_info->u.hvm.apic);
   2.301 -        printf("    acpi: %d\n", b_info->u.hvm.acpi);
   2.302 -        printf("    nx: %d\n", b_info->u.hvm.nx);
   2.303 -        printf("    viridian: %d\n", b_info->u.hvm.viridian);
   2.304 -    } else {
   2.305 -        printf("cmdline: %s\n", b_info->u.pv.cmdline);
   2.306 -        printf("ramdisk: %s\n", b_info->u.pv.ramdisk);
   2.307 -    }
   2.308 -
   2.309 -    for (i = 0; i < num_disks; i++) {
   2.310 -        printf("\n\n\n*** disks_info: %d ***\n", i);
   2.311 -        printf("backend_domid %d\n", disks[i].backend_domid);
   2.312 -        printf("domid %d\n", disks[i].domid);
   2.313 -        printf("physpath %s\n", disks[i].physpath);
   2.314 -        printf("phystype %d\n", disks[i].phystype);
   2.315 -        printf("virtpath %s\n", disks[i].virtpath);
   2.316 -        printf("unpluggable %d\n", disks[i].unpluggable);
   2.317 -        printf("readwrite %d\n", disks[i].readwrite);
   2.318 -        printf("is_cdrom %d\n", disks[i].is_cdrom);
   2.319 -    }
   2.320 -
   2.321 -    for (i = 0; i < num_vifs; i++) {
   2.322 -        printf("\n\n\n*** vifs_info: %d ***\n", i);
   2.323 -        printf("backend_domid %d\n", vifs[i].backend_domid);
   2.324 -        printf("domid %d\n", vifs[i].domid);
   2.325 -        printf("devid %d\n", vifs[i].devid);
   2.326 -        printf("mtu %d\n", vifs[i].mtu);
   2.327 -        printf("model %s\n", vifs[i].model);
   2.328 -        printf("mac %02x:%02x:%02x:%02x:%02x:%02x\n", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   2.329 -    }
   2.330 -
   2.331 -    for (i = 0; i < num_pcidevs; i++) {
   2.332 -        printf("\n\n\n*** pcidevs_info: %d ***\n", i);
   2.333 -        printf("pci dev "PCI_BDF_VDEVFN"\n", pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func, pcidevs[i].vdevfn);
   2.334 -        printf("opts msitranslate %d power_mgmt %d\n", pcidevs[i].msitranslate, pcidevs[i].power_mgmt);
   2.335 -    }
   2.336 -
   2.337 -    for (i = 0; i < num_vfbs; i++) {
   2.338 -        printf("\n\n\n*** vfbs_info: %d ***\n", i);
   2.339 -        printf("backend_domid %d\n", vfbs[i].backend_domid);
   2.340 -        printf("domid %d\n", vfbs[i].domid);
   2.341 -        printf("devid %d\n", vfbs[i].devid);
   2.342 -        printf("vnc: %d\n", vfbs[i].vnc);
   2.343 -        printf("vnclisten: %s\n", vfbs[i].vnclisten);
   2.344 -        printf("vncdisplay: %d\n", vfbs[i].vncdisplay);
   2.345 -        printf("vncunused: %d\n", vfbs[i].vncunused);
   2.346 -        printf("keymap: %s\n", vfbs[i].keymap);
   2.347 -        printf("sdl: %d\n", vfbs[i].sdl);
   2.348 -        printf("opengl: %d\n", vfbs[i].opengl);
   2.349 -        printf("display: %s\n", vfbs[i].display);
   2.350 -        printf("xauthority: %s\n", vfbs[i].xauthority);
   2.351 -    }
   2.352 -
   2.353 -    if (c_info->hvm) {
   2.354 -        printf("\n\n\n*** device_model_info ***\n");
   2.355 -        printf("domid: %d\n", dm_info->domid);
   2.356 -        printf("dom_name: %s\n", dm_info->dom_name);
   2.357 -        printf("device_model: %s\n", dm_info->device_model);
   2.358 -        printf("videoram: %d\n", dm_info->videoram);
   2.359 -        printf("stdvga: %d\n", dm_info->stdvga);
   2.360 -        printf("vnc: %d\n", dm_info->vnc);
   2.361 -        printf("vnclisten: %s\n", dm_info->vnclisten);
   2.362 -        printf("vncdisplay: %d\n", dm_info->vncdisplay);
   2.363 -        printf("vncunused: %d\n", dm_info->vncunused);
   2.364 -        printf("keymap: %s\n", dm_info->keymap);
   2.365 -        printf("sdl: %d\n", dm_info->sdl);
   2.366 -        printf("opengl: %d\n", dm_info->opengl);
   2.367 -        printf("nographic: %d\n", dm_info->nographic);
   2.368 -        printf("serial: %s\n", dm_info->serial);
   2.369 -        printf("boot: %s\n", dm_info->boot);
   2.370 -        printf("usb: %d\n", dm_info->usb);
   2.371 -        printf("usbdevice: %s\n", dm_info->usbdevice);
   2.372 -        printf("apic: %d\n", dm_info->apic);
   2.373 -    }
   2.374 -}
   2.375 -
   2.376 -static void parse_config_data(const char *configfile_filename_report,
   2.377 -                              const char *configfile_data,
   2.378 -                              int configfile_len,
   2.379 -                              libxl_domain_create_info *c_info,
   2.380 -                              libxl_domain_build_info *b_info,
   2.381 -                              libxl_device_disk **disks,
   2.382 -                              int *num_disks,
   2.383 -                              libxl_device_nic **vifs,
   2.384 -                              int *num_vifs,
   2.385 -                              libxl_device_pci **pcidevs,
   2.386 -                              int *num_pcidevs,
   2.387 -                              libxl_device_vfb **vfbs,
   2.388 -                              int *num_vfbs,
   2.389 -                              libxl_device_vkb **vkbs,
   2.390 -                              int *num_vkbs,
   2.391 -                              libxl_device_model_info *dm_info)
   2.392 -{
   2.393 -    const char *buf;
   2.394 -    long l;
   2.395 -    XLU_Config *config;
   2.396 -    XLU_ConfigList *vbds, *nics, *pcis, *cvfbs;
   2.397 -    int pci_power_mgmt = 0;
   2.398 -    int pci_msitranslate = 1;
   2.399 -    int i, e;
   2.400 -
   2.401 -    config= xlu_cfg_init(stderr, configfile_filename_report);
   2.402 -    if (!config) {
   2.403 -        fprintf(stderr, "Failed to allocate for configuration\n");
   2.404 -        exit(1);
   2.405 -    }
   2.406 -
   2.407 -    e= xlu_cfg_readdata(config, configfile_data, configfile_len);
   2.408 -    if (e) {
   2.409 -        fprintf(stderr, "Failed to parse config file: %s\n", strerror(e));
   2.410 -        exit(1);
   2.411 -    }
   2.412 -
   2.413 -    init_create_info(c_info);
   2.414 -
   2.415 -    c_info->hvm = 0;
   2.416 -    if (!xlu_cfg_get_string (config, "builder", &buf) &&
   2.417 -        !strncmp(buf, "hvm", strlen(buf)))
   2.418 -        c_info->hvm = 1;
   2.419 -
   2.420 -    /* hap is missing */
   2.421 -    if (!xlu_cfg_get_string (config, "name", &buf))
   2.422 -        c_info->name = strdup(buf);
   2.423 -    else
   2.424 -        c_info->name = "test";
   2.425 -    for (i = 0; i < 16; i++) {
   2.426 -        c_info->uuid[i] = rand();
   2.427 -    }
   2.428 -
   2.429 -    if (!xlu_cfg_get_long(config, "oos", &l))
   2.430 -        c_info->oos = l;
   2.431 -
   2.432 -    init_build_info(b_info, c_info);
   2.433 -
   2.434 -    /* the following is the actual config parsing with overriding values in the structures */
   2.435 -    if (!xlu_cfg_get_long (config, "vcpus", &l))
   2.436 -        b_info->max_vcpus = l;
   2.437 -
   2.438 -    if (!xlu_cfg_get_long (config, "memory", &l)) {
   2.439 -        b_info->max_memkb = l * 1024;
   2.440 -        b_info->target_memkb = b_info->max_memkb;
   2.441 -    }
   2.442 -
   2.443 -    if (!xlu_cfg_get_long(config, "tsc_mode", &l))
   2.444 -        b_info->tsc_mode = l;
   2.445 -
   2.446 -    if (!xlu_cfg_get_long (config, "shadow_memory", &l))
   2.447 -        b_info->shadow_memkb = l * 1024;
   2.448 -
   2.449 -    if (!xlu_cfg_get_long (config, "videoram", &l))
   2.450 -        b_info->video_memkb = l * 1024;
   2.451 -
   2.452 -    if (!xlu_cfg_get_string (config, "kernel", &buf))
   2.453 -        b_info->kernel = strdup(buf);
   2.454 -
   2.455 -    if (c_info->hvm == 1) {
   2.456 -        if (!xlu_cfg_get_long (config, "pae", &l))
   2.457 -            b_info->u.hvm.pae = l;
   2.458 -        if (!xlu_cfg_get_long (config, "apic", &l))
   2.459 -            b_info->u.hvm.apic = l;
   2.460 -        if (!xlu_cfg_get_long (config, "acpi", &l))
   2.461 -            b_info->u.hvm.acpi = l;
   2.462 -        if (!xlu_cfg_get_long (config, "nx", &l))
   2.463 -            b_info->u.hvm.nx = l;
   2.464 -        if (!xlu_cfg_get_long (config, "viridian", &l))
   2.465 -            b_info->u.hvm.viridian = l;
   2.466 -    } else {
   2.467 -        char *cmdline;
   2.468 -        if (!xlu_cfg_get_string (config, "root", &buf)) {
   2.469 -            asprintf(&cmdline, "root=%s", buf);
   2.470 -            b_info->u.pv.cmdline = cmdline;
   2.471 -        }
   2.472 -        if (!xlu_cfg_get_string (config, "ramdisk", &buf))
   2.473 -            b_info->u.pv.ramdisk = strdup(buf);
   2.474 -    }
   2.475 -
   2.476 -    if (!xlu_cfg_get_list (config, "disk", &vbds, 0)) {
   2.477 -        *num_disks = 0;
   2.478 -        *disks = NULL;
   2.479 -        while ((buf = xlu_cfg_get_listitem (vbds, *num_disks)) != NULL) {
   2.480 -            char *buf2 = strdup(buf);
   2.481 -            char *p, *p2;
   2.482 -            *disks = (libxl_device_disk *) realloc(*disks, sizeof (libxl_device_disk) * ((*num_disks) + 1));
   2.483 -            (*disks)[*num_disks].backend_domid = 0;
   2.484 -            (*disks)[*num_disks].domid = 0;
   2.485 -            (*disks)[*num_disks].unpluggable = 0;
   2.486 -            p = strtok(buf2, ",:");
   2.487 -            while (*p == ' ')
   2.488 -                p++;
   2.489 -            if (!strcmp(p, "phy")) {
   2.490 -                (*disks)[*num_disks].phystype = PHYSTYPE_PHY;
   2.491 -            } else if (!strcmp(p, "file")) {
   2.492 -                (*disks)[*num_disks].phystype = PHYSTYPE_FILE;
   2.493 -            } else if (!strcmp(p, "tap")) {
   2.494 -                p = strtok(NULL, ":");
   2.495 -                if (!strcmp(p, "aio")) {
   2.496 -                    (*disks)[*num_disks].phystype = PHYSTYPE_AIO;
   2.497 -                } else if (!strcmp(p, "vhd")) {
   2.498 -                    (*disks)[*num_disks].phystype = PHYSTYPE_VHD;
   2.499 -                } else if (!strcmp(p, "qcow")) {
   2.500 -                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW;
   2.501 -                } else if (!strcmp(p, "qcow2")) {
   2.502 -                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW2;
   2.503 -                }
   2.504 -            }
   2.505 -            p = strtok(NULL, ",");
   2.506 -            while (*p == ' ')
   2.507 -                p++;
   2.508 -            (*disks)[*num_disks].physpath= strdup(p);
   2.509 -            p = strtok(NULL, ",");
   2.510 -            while (*p == ' ')
   2.511 -                p++;
   2.512 -            p2 = strchr(p, ':');
   2.513 -            if (p2 == NULL) {
   2.514 -                (*disks)[*num_disks].virtpath = strdup(p);
   2.515 -                (*disks)[*num_disks].is_cdrom = 0;
   2.516 -                (*disks)[*num_disks].unpluggable = 1;
   2.517 -            } else {
   2.518 -                *p2 = '\0';
   2.519 -                (*disks)[*num_disks].virtpath = strdup(p);
   2.520 -                if (!strcmp(p2 + 1, "cdrom")) {
   2.521 -                    (*disks)[*num_disks].is_cdrom = 1;
   2.522 -                    (*disks)[*num_disks].unpluggable = 1;
   2.523 -                } else
   2.524 -                    (*disks)[*num_disks].is_cdrom = 0;
   2.525 -            }
   2.526 -            p = strtok(NULL, ",");
   2.527 -            while (*p == ' ')
   2.528 -                p++;
   2.529 -            (*disks)[*num_disks].readwrite = (p[0] == 'w') ? 1 : 0;
   2.530 -            free(buf2);
   2.531 -            *num_disks = (*num_disks) + 1;
   2.532 -        }
   2.533 -    }
   2.534 -
   2.535 -    if (!xlu_cfg_get_list (config, "vif", &nics, 0)) {
   2.536 -        *num_vifs = 0;
   2.537 -        *vifs = NULL;
   2.538 -        while ((buf = xlu_cfg_get_listitem (nics, *num_vifs)) != NULL) {
   2.539 -            char *buf2 = strdup(buf);
   2.540 -            char *p, *p2;
   2.541 -            *vifs = (libxl_device_nic *) realloc(*vifs, sizeof (libxl_device_nic) * ((*num_vifs) + 1));
   2.542 -            init_nic_info((*vifs) + (*num_vifs), (*num_vifs) + 1);
   2.543 -            p = strtok(buf2, ",");
   2.544 -            if (!p)
   2.545 -                goto skip;
   2.546 -            do {
   2.547 -                while (*p == ' ')
   2.548 -                    p++;
   2.549 -                if ((p2 = strchr(p, '=')) == NULL)
   2.550 -                    break;
   2.551 -                *p2 = '\0';
   2.552 -                if (!strcmp(p, "model")) {
   2.553 -                    (*vifs)[*num_vifs].model = strdup(p2 + 1);
   2.554 -                } else if (!strcmp(p, "mac")) {
   2.555 -                    char *p3 = p2 + 1;
   2.556 -                    *(p3 + 2) = '\0';
   2.557 -                    (*vifs)[*num_vifs].mac[0] = strtol(p3, NULL, 16);
   2.558 -                    p3 = p3 + 3;
   2.559 -                    *(p3 + 2) = '\0';
   2.560 -                    (*vifs)[*num_vifs].mac[1] = strtol(p3, NULL, 16);
   2.561 -                    p3 = p3 + 3;
   2.562 -                    *(p3 + 2) = '\0';
   2.563 -                    (*vifs)[*num_vifs].mac[2] = strtol(p3, NULL, 16);
   2.564 -                    p3 = p3 + 3;
   2.565 -                    *(p3 + 2) = '\0';
   2.566 -                    (*vifs)[*num_vifs].mac[3] = strtol(p3, NULL, 16);
   2.567 -                    p3 = p3 + 3;
   2.568 -                    *(p3 + 2) = '\0';
   2.569 -                    (*vifs)[*num_vifs].mac[4] = strtol(p3, NULL, 16);
   2.570 -                    p3 = p3 + 3;
   2.571 -                    *(p3 + 2) = '\0';
   2.572 -                    (*vifs)[*num_vifs].mac[5] = strtol(p3, NULL, 16);
   2.573 -                } else if (!strcmp(p, "bridge")) {
   2.574 -                    (*vifs)[*num_vifs].bridge = strdup(p2 + 1);
   2.575 -                } else if (!strcmp(p, "type")) {
   2.576 -                    if (!strcmp(p2 + 1, "ioemu"))
   2.577 -                        (*vifs)[*num_vifs].nictype = NICTYPE_IOEMU;
   2.578 -                    else
   2.579 -                        (*vifs)[*num_vifs].nictype = NICTYPE_VIF;
   2.580 -                } else if (!strcmp(p, "ip")) {
   2.581 -                    inet_pton(AF_INET, p2 + 1, &((*vifs)[*num_vifs].ip));
   2.582 -                } else if (!strcmp(p, "script")) {
   2.583 -                    (*vifs)[*num_vifs].script = strdup(p2 + 1);
   2.584 -                } else if (!strcmp(p, "vifname")) {
   2.585 -                    (*vifs)[*num_vifs].ifname = strdup(p2 + 1);
   2.586 -                } else if (!strcmp(p, "rate")) {
   2.587 -                    fprintf(stderr, "the rate parameter for vifs is currently not supported\n");
   2.588 -                } else if (!strcmp(p, "accel")) {
   2.589 -                    fprintf(stderr, "the accel parameter for vifs is currently not supported\n");
   2.590 -                }
   2.591 -            } while ((p = strtok(NULL, ",")) != NULL);
   2.592 -skip:
   2.593 -            free(buf2);
   2.594 -            *num_vifs = (*num_vifs) + 1;
   2.595 -        }
   2.596 -    }
   2.597 -
   2.598 -    if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0)) {
   2.599 -        *num_vfbs = 0;
   2.600 -        *num_vkbs = 0;
   2.601 -        *vfbs = NULL;
   2.602 -        *vkbs = NULL;
   2.603 -        while ((buf = xlu_cfg_get_listitem (cvfbs, *num_vfbs)) != NULL) {
   2.604 -            char *buf2 = strdup(buf);
   2.605 -            char *p, *p2;
   2.606 -            *vfbs = (libxl_device_vfb *) realloc(*vfbs, sizeof(libxl_device_vfb) * ((*num_vfbs) + 1));
   2.607 -            init_vfb_info((*vfbs) + (*num_vfbs), (*num_vfbs));
   2.608 -
   2.609 -            *vkbs = (libxl_device_vkb *) realloc(*vkbs, sizeof(libxl_device_vkb) * ((*num_vkbs) + 1));
   2.610 -            init_vkb_info((*vkbs) + (*num_vkbs), (*num_vkbs));
   2.611 -
   2.612 -            p = strtok(buf2, ",");
   2.613 -            if (!p)
   2.614 -                goto skip_vfb;
   2.615 -            do {
   2.616 -                while (*p == ' ')
   2.617 -                    p++;
   2.618 -                if ((p2 = strchr(p, '=')) == NULL)
   2.619 -                    break;
   2.620 -                *p2 = '\0';
   2.621 -                if (!strcmp(p, "vnc")) {
   2.622 -                    (*vfbs)[*num_vfbs].vnc = atoi(p2 + 1);
   2.623 -                } else if (!strcmp(p, "vnclisten")) {
   2.624 -                    (*vfbs)[*num_vfbs].vnclisten = strdup(p2 + 1);
   2.625 -                } else if (!strcmp(p, "vncdisplay")) {
   2.626 -                    (*vfbs)[*num_vfbs].vncdisplay = atoi(p2 + 1);
   2.627 -                } else if (!strcmp(p, "vncunused")) {
   2.628 -                    (*vfbs)[*num_vfbs].vncunused = atoi(p2 + 1);
   2.629 -                } else if (!strcmp(p, "keymap")) {
   2.630 -                    (*vfbs)[*num_vfbs].keymap = strdup(p2 + 1);
   2.631 -                } else if (!strcmp(p, "sdl")) {
   2.632 -                    (*vfbs)[*num_vfbs].sdl = atoi(p2 + 1);
   2.633 -                } else if (!strcmp(p, "opengl")) {
   2.634 -                    (*vfbs)[*num_vfbs].opengl = atoi(p2 + 1);
   2.635 -                } else if (!strcmp(p, "display")) {
   2.636 -                    (*vfbs)[*num_vfbs].display = strdup(p2 + 1);
   2.637 -                } else if (!strcmp(p, "xauthority")) {
   2.638 -                    (*vfbs)[*num_vfbs].xauthority = strdup(p2 + 1);
   2.639 -                }
   2.640 -            } while ((p = strtok(NULL, ",")) != NULL);
   2.641 -skip_vfb:
   2.642 -            free(buf2);
   2.643 -            *num_vfbs = (*num_vfbs) + 1;
   2.644 -            *num_vkbs = (*num_vkbs) + 1;
   2.645 -        }
   2.646 -    }
   2.647 -
   2.648 -    if (!xlu_cfg_get_long (config, "pci_msitranslate", &l))
   2.649 -        pci_msitranslate = l;
   2.650 -
   2.651 -    if (!xlu_cfg_get_long (config, "pci_power_mgmt", &l))
   2.652 -        pci_power_mgmt = l;
   2.653 -
   2.654 -    if (!xlu_cfg_get_list (config, "pci", &pcis, 0)) {
   2.655 -        *num_pcidevs = 0;
   2.656 -        *pcidevs = NULL;
   2.657 -        while ((buf = xlu_cfg_get_listitem (pcis, *num_pcidevs)) != NULL) {
   2.658 -            unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
   2.659 -            char *buf2 = strdup(buf);
   2.660 -            char *p;
   2.661 -            *pcidevs = (libxl_device_pci *) realloc(*pcidevs, sizeof (libxl_device_pci) * ((*num_pcidevs) + 1));
   2.662 -            memset(*pcidevs + *num_pcidevs, 0x00, sizeof(libxl_device_pci));
   2.663 -            p = strtok(buf2, ",");
   2.664 -            if (!p)
   2.665 -                goto skip_pci;
   2.666 -            if (!sscanf(p, PCI_BDF_VDEVFN, &domain, &bus, &dev, &func, &vdevfn)) {
   2.667 -                sscanf(p, "%02x:%02x.%01x@%02x", &bus, &dev, &func, &vdevfn);
   2.668 -                domain = 0;
   2.669 -            }
   2.670 -            libxl_device_pci_init(*pcidevs + *num_pcidevs, domain, bus, dev, func, vdevfn);
   2.671 -            (*pcidevs)[*num_pcidevs].msitranslate = pci_msitranslate;
   2.672 -            (*pcidevs)[*num_pcidevs].power_mgmt = pci_power_mgmt;
   2.673 -            while ((p = strtok(NULL, ",=")) != NULL) {
   2.674 -                while (*p == ' ')
   2.675 -                    p++;
   2.676 -                if (!strcmp(p, "msitranslate")) {
   2.677 -                    p = strtok(NULL, ",=");
   2.678 -                    (*pcidevs)[*num_pcidevs].msitranslate = atoi(p);
   2.679 -                } else if (!strcmp(p, "power_mgmt")) {
   2.680 -                    p = strtok(NULL, ",=");
   2.681 -                    (*pcidevs)[*num_pcidevs].power_mgmt = atoi(p);
   2.682 -                }
   2.683 -            }
   2.684 -            *num_pcidevs = (*num_pcidevs) + 1;
   2.685 -skip_pci:
   2.686 -            free(buf2);
   2.687 -        }
   2.688 -    }
   2.689 -
   2.690 -    if (c_info->hvm == 1) {
   2.691 -        /* init dm from c and b */
   2.692 -        init_dm_info(dm_info, c_info, b_info);
   2.693 -
   2.694 -        /* then process config related to dm */
   2.695 -        if (!xlu_cfg_get_string (config, "device_model", &buf))
   2.696 -            dm_info->device_model = strdup(buf);
   2.697 -        if (!xlu_cfg_get_long (config, "stdvga", &l))
   2.698 -            dm_info->stdvga = l;
   2.699 -        if (!xlu_cfg_get_long (config, "vnc", &l))
   2.700 -            dm_info->vnc = l;
   2.701 -        if (!xlu_cfg_get_string (config, "vnclisten", &buf))
   2.702 -            dm_info->vnclisten = strdup(buf);
   2.703 -        if (!xlu_cfg_get_long (config, "vncdisplay", &l))
   2.704 -            dm_info->vncdisplay = l;
   2.705 -        if (!xlu_cfg_get_long (config, "vncunused", &l))
   2.706 -            dm_info->vncunused = l;
   2.707 -        if (!xlu_cfg_get_string (config, "keymap", &buf))
   2.708 -            dm_info->keymap = strdup(buf);
   2.709 -        if (!xlu_cfg_get_long (config, "sdl", &l))
   2.710 -            dm_info->sdl = l;
   2.711 -        if (!xlu_cfg_get_long (config, "opengl", &l))
   2.712 -            dm_info->opengl = l;
   2.713 -        if (!xlu_cfg_get_long (config, "nographic", &l))
   2.714 -            dm_info->nographic = l;
   2.715 -        if (!xlu_cfg_get_string (config, "serial", &buf))
   2.716 -            dm_info->serial = strdup(buf);
   2.717 -        if (!xlu_cfg_get_string (config, "boot", &buf))
   2.718 -            dm_info->boot = strdup(buf);
   2.719 -        if (!xlu_cfg_get_long (config, "usb", &l))
   2.720 -            dm_info->usb = l;
   2.721 -        if (!xlu_cfg_get_string (config, "usbdevice", &buf))
   2.722 -            dm_info->usbdevice = strdup(buf);
   2.723 -    }
   2.724 -
   2.725 -    dm_info->type = c_info->hvm ? XENFV : XENPV;
   2.726 -
   2.727 -    xlu_cfg_destroy(config);
   2.728 -}
   2.729 -
   2.730 -#define CHK_ERRNO( call ) ({                                            \
   2.731 -        int chk_errno = (call);                                         \
   2.732 -        if (chk_errno) {                                                \
   2.733 -            fprintf(stderr,"xl: fatal error: %s:%d: %s: %s\n",          \
   2.734 -                    __FILE__,__LINE__, strerror(chk_errno), #call);     \
   2.735 -            exit(-ERROR_FAIL);                                          \
   2.736 -        }                                                               \
   2.737 -    })
   2.738 -
   2.739 -#define MUST( call ) ({                                                 \
   2.740 -        int must_rc = (call);                                           \
   2.741 -        if (must_rc) {                                                  \
   2.742 -            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: %s\n",       \
   2.743 -                    __FILE__,__LINE__, must_rc, #call);                 \
   2.744 -            exit(-must_rc);                                             \
   2.745 -        }                                                               \
   2.746 -    })
   2.747 -
   2.748 -static void *xmalloc(size_t sz) {
   2.749 -    void *r;
   2.750 -    r = malloc(sz);
   2.751 -    if (!r) { fprintf(stderr,"xl: Unable to malloc %lu bytes.\n",
   2.752 -                      (unsigned long)sz); exit(-ERROR_FAIL); }
   2.753 -    return r;
   2.754 -}
   2.755 -
   2.756 -static void *xrealloc(void *ptr, size_t sz) {
   2.757 -    void *r;
   2.758 -    if (!sz) { free(ptr); return 0; }
   2.759 -      /* realloc(non-0, 0) has a useless return value;
   2.760 -       * but xrealloc(anything, 0) is like free
   2.761 -       */
   2.762 -    r = realloc(ptr, sz);
   2.763 -    if (!r) { fprintf(stderr,"xl: Unable to realloc to %lu bytes.\n",
   2.764 -                      (unsigned long)sz); exit(-ERROR_FAIL); }
   2.765 -    return r;
   2.766 -}
   2.767 -
   2.768 -static int create_domain(int debug, int daemonize, const char *config_file, const char *restore_file, int paused, int migrate_fd /* -1 means none */, char **migration_domname_r)
   2.769 -{
   2.770 -    libxl_domain_create_info info1;
   2.771 -    libxl_domain_build_info info2;
   2.772 -    libxl_domain_build_state state;
   2.773 -    libxl_device_model_info dm_info;
   2.774 -    libxl_device_disk *disks = NULL;
   2.775 -    libxl_device_nic *vifs = NULL;
   2.776 -    libxl_device_pci *pcidevs = NULL;
   2.777 -    libxl_device_vfb *vfbs = NULL;
   2.778 -    libxl_device_vkb *vkbs = NULL;
   2.779 -    libxl_device_console console;
   2.780 -    int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 0;
   2.781 -    int i, fd;
   2.782 -    int need_daemon = 1;
   2.783 -    int ret, rc;
   2.784 -    libxl_device_model_starting *dm_starting = 0;
   2.785 -    libxl_waiter *w1 = NULL, *w2 = NULL;
   2.786 -    void *config_data = 0;
   2.787 -    int config_len = 0;
   2.788 -    int restore_fd = -1;
   2.789 -    struct save_file_header hdr;
   2.790 -
   2.791 -    memset(&dm_info, 0x00, sizeof(dm_info));
   2.792 -
   2.793 -    if (restore_file) {
   2.794 -        uint8_t *optdata_begin = 0;
   2.795 -        const uint8_t *optdata_here = 0;
   2.796 -        union { uint32_t u32; char b[4]; } u32buf;
   2.797 -        uint32_t badflags;
   2.798 -
   2.799 -        restore_fd = migrate_fd >= 0 ? migrate_fd :
   2.800 -            open(restore_file, O_RDONLY);
   2.801 -
   2.802 -        CHK_ERRNO( libxl_read_exactly(&ctx, restore_fd, &hdr,
   2.803 -                   sizeof(hdr), restore_file, "header") );
   2.804 -        if (memcmp(hdr.magic, savefileheader_magic, sizeof(hdr.magic))) {
   2.805 -            fprintf(stderr, "File has wrong magic number -"
   2.806 -                    " corrupt or for a different tool?\n");
   2.807 -            return ERROR_INVAL;
   2.808 -        }
   2.809 -        if (hdr.byteorder != SAVEFILE_BYTEORDER_VALUE) {
   2.810 -            fprintf(stderr, "File has wrong byte order\n");
   2.811 -            return ERROR_INVAL;
   2.812 -        }
   2.813 -        fprintf(stderr, "Loading new save file %s"
   2.814 -                " (new xl fmt info"
   2.815 -                " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n",
   2.816 -                restore_file, hdr.mandatory_flags, hdr.optional_flags,
   2.817 -                hdr.optional_data_len);
   2.818 -
   2.819 -        badflags = hdr.mandatory_flags & ~( 0 /* none understood yet */ );
   2.820 -        if (badflags) {
   2.821 -            fprintf(stderr, "Savefile has mandatory flag(s) 0x%"PRIx32" "
   2.822 -                    "which are not supported; need newer xl\n",
   2.823 -                    badflags);
   2.824 -            return ERROR_INVAL;
   2.825 -        }
   2.826 -        if (hdr.optional_data_len) {
   2.827 -            optdata_begin = xmalloc(hdr.optional_data_len);
   2.828 -            CHK_ERRNO( libxl_read_exactly(&ctx, restore_fd, optdata_begin,
   2.829 -                   hdr.optional_data_len, restore_file, "optdata") );
   2.830 -        }
   2.831 -
   2.832 -#define OPTDATA_LEFT  (hdr.optional_data_len - (optdata_here - optdata_begin))
   2.833 -#define WITH_OPTDATA(amt, body)                                 \
   2.834 -            if (OPTDATA_LEFT < (amt)) {                         \
   2.835 -                fprintf(stderr, "Savefile truncated.\n");       \
   2.836 -                return ERROR_INVAL;                             \
   2.837 -            } else {                                            \
   2.838 -                body;                                           \
   2.839 -                optdata_here += (amt);                          \
   2.840 -            }
   2.841 -
   2.842 -        optdata_here = optdata_begin;
   2.843 -
   2.844 -        if (OPTDATA_LEFT) {
   2.845 -            fprintf(stderr, " Savefile contains xl domain config\n");
   2.846 -            WITH_OPTDATA(4, {
   2.847 -                memcpy(u32buf.b, optdata_here, 4);
   2.848 -                config_len = u32buf.u32;
   2.849 -            });
   2.850 -            WITH_OPTDATA(config_len, {
   2.851 -                config_data = xmalloc(config_len);
   2.852 -                memcpy(config_data, optdata_here, config_len);
   2.853 -            });
   2.854 -        }
   2.855 -
   2.856 -    }
   2.857 -
   2.858 -    if (config_file) {
   2.859 -        free(config_data);  config_data = 0;
   2.860 -        ret = libxl_read_file_contents(&ctx, config_file,
   2.861 -                                       &config_data, &config_len);
   2.862 -        if (ret) { fprintf(stderr, "Failed to read config file: %s: %s\n",
   2.863 -                           config_file, strerror(errno)); return ERROR_FAIL; }
   2.864 -    } else {
   2.865 -        if (!config_data) {
   2.866 -            fprintf(stderr, "Config file not specified and"
   2.867 -                    " none in save file\n");
   2.868 -            return ERROR_INVAL;
   2.869 -        }
   2.870 -        config_file = "<saved>";
   2.871 -    }
   2.872 -
   2.873 -    printf("Parsing config file %s\n", config_file);
   2.874 -
   2.875 -    parse_config_data(config_file, config_data, config_len, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info);
   2.876 -
   2.877 -    if (migrate_fd >= 0) {
   2.878 -        if (info1.name) {
   2.879 -            /* when we receive a domain we get its name from the config
   2.880 -             * file; and we receive it to a temporary name */
   2.881 -            assert(!common_domname);
   2.882 -            common_domname = info1.name;
   2.883 -            asprintf(migration_domname_r, "%s--incoming", info1.name);
   2.884 -            info1.name = *migration_domname_r;
   2.885 -        }
   2.886 -    }
   2.887 -
   2.888 -    if (debug)
   2.889 -        printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info);
   2.890 -
   2.891 -start:
   2.892 -    domid = 0;
   2.893 -
   2.894 -    ret = libxl_domain_make(&ctx, &info1, &domid);
   2.895 -    if (ret) {
   2.896 -        fprintf(stderr, "cannot make domain: %d\n", ret);
   2.897 -        return ERROR_FAIL;
   2.898 -    }
   2.899 -
   2.900 -    ret = libxl_userdata_store(&ctx, domid, "xl",
   2.901 -                                    config_data, config_len);
   2.902 -    if (ret) {
   2.903 -        perror("cannot save config file");
   2.904 -        return ERROR_FAIL;
   2.905 -    }
   2.906 -
   2.907 -    if (!restore_file || !need_daemon) {
   2.908 -        if (dm_info.saved_state) {
   2.909 -            free(dm_info.saved_state);
   2.910 -            dm_info.saved_state = NULL;
   2.911 -        }
   2.912 -        ret = libxl_domain_build(&ctx, &info2, domid, &state);
   2.913 -    } else {
   2.914 -        ret = libxl_domain_restore(&ctx, &info2, domid, restore_fd, &state, &dm_info);
   2.915 -    }
   2.916 -
   2.917 -    if (ret) {
   2.918 -        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
   2.919 -        return ERROR_FAIL;
   2.920 -    }
   2.921 -
   2.922 -    for (i = 0; i < num_disks; i++) {
   2.923 -        disks[i].domid = domid;
   2.924 -        ret = libxl_device_disk_add(&ctx, domid, &disks[i]);
   2.925 -        if (ret) {
   2.926 -            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
   2.927 -            return ERROR_FAIL;
   2.928 -        }
   2.929 -    }
   2.930 -    for (i = 0; i < num_vifs; i++) {
   2.931 -        vifs[i].domid = domid;
   2.932 -        ret = libxl_device_nic_add(&ctx, domid, &vifs[i]);
   2.933 -        if (ret) {
   2.934 -            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
   2.935 -            return ERROR_FAIL;
   2.936 -        }
   2.937 -    }
   2.938 -    if (info1.hvm) {
   2.939 -        dm_info.domid = domid;
   2.940 -        MUST( libxl_create_device_model(&ctx, &dm_info, disks, num_disks,
   2.941 -                                        vifs, num_vifs, &dm_starting) );
   2.942 -    } else {
   2.943 -        for (i = 0; i < num_vfbs; i++) {
   2.944 -            vfbs[i].domid = domid;
   2.945 -            libxl_device_vfb_add(&ctx, domid, &vfbs[i]);
   2.946 -            vkbs[i].domid = domid;
   2.947 -            libxl_device_vkb_add(&ctx, domid, &vkbs[i]);
   2.948 -        }
   2.949 -        init_console_info(&console, 0, &state);
   2.950 -        console.domid = domid;
   2.951 -        if (num_vfbs)
   2.952 -            console.constype = CONSTYPE_IOEMU;
   2.953 -        libxl_device_console_add(&ctx, domid, &console);
   2.954 -        if (num_vfbs)
   2.955 -            libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console, &dm_starting);
   2.956 -    }
   2.957 -
   2.958 -    if (dm_starting)
   2.959 -        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
   2.960 -    for (i = 0; i < num_pcidevs; i++)
   2.961 -        libxl_device_pci_add(&ctx, domid, &pcidevs[i]);
   2.962 -
   2.963 -    if (!paused)
   2.964 -        libxl_domain_unpause(&ctx, domid);
   2.965 -
   2.966 -    if (!daemonize)
   2.967 -        return 0; /* caller gets success in parent */
   2.968 -
   2.969 -    if (need_daemon) {
   2.970 -        char *fullname, *name;
   2.971 -        pid_t child1, got_child;
   2.972 -        int nullfd;
   2.973 -
   2.974 -        child1 = libxl_fork(&ctx);
   2.975 -        if (child1) {
   2.976 -            int status;
   2.977 -            for (;;) {
   2.978 -                got_child = waitpid(child1, &status, 0);
   2.979 -                if (got_child == child1) break;
   2.980 -                assert(got_child == -1);
   2.981 -                if (errno != EINTR) {
   2.982 -                    perror("failed to wait for daemonizing child");
   2.983 -                    return ERROR_FAIL;
   2.984 -                }
   2.985 -            }
   2.986 -            if (status) {
   2.987 -                libxl_report_child_exitstatus(&ctx, XL_LOG_ERROR,
   2.988 -                           "daemonizing child", child1, status);
   2.989 -                return ERROR_FAIL;
   2.990 -            }
   2.991 -            return 0; /* caller gets success in parent */
   2.992 -        }
   2.993 -
   2.994 -        rc = libxl_ctx_postfork(&ctx);
   2.995 -        if (rc) {
   2.996 -            LOG("failed to reinitialise context after fork");
   2.997 -            exit(-1);
   2.998 -        }
   2.999 -
  2.1000 -        asprintf(&name, "xl-%s", info1.name);
  2.1001 -        rc = libxl_create_logfile(&ctx, name, &fullname);
  2.1002 -        if (rc) {
  2.1003 -            LOG("failed to open logfile %s",fullname,strerror(errno));
  2.1004 -            exit(-1);
  2.1005 -        }
  2.1006 -
  2.1007 -        CHK_ERRNO(( logfile = open(fullname, O_WRONLY|O_CREAT, 0644) )<0);
  2.1008 -        free(fullname);
  2.1009 -        free(name);
  2.1010 -
  2.1011 -        CHK_ERRNO(( nullfd = open("/dev/null", O_RDONLY) )<0);
  2.1012 -        dup2(nullfd, 0);
  2.1013 -        dup2(logfile, 1);
  2.1014 -        dup2(logfile, 2);
  2.1015 -
  2.1016 -        daemon(0, 1);
  2.1017 -        need_daemon = 0;
  2.1018 -    }
  2.1019 -    LOG("Waiting for domain %s (domid %d) to die [pid %ld]",
  2.1020 -        info1.name, domid, (long)getpid());
  2.1021 -    w1 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter) * num_disks);
  2.1022 -    w2 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
  2.1023 -    libxl_wait_for_disk_ejects(&ctx, domid, disks, num_disks, w1);
  2.1024 -    libxl_wait_for_domain_death(&ctx, domid, w2);
  2.1025 -    libxl_get_wait_fd(&ctx, &fd);
  2.1026 -    while (1) {
  2.1027 -        int ret;
  2.1028 -        fd_set rfds;
  2.1029 -        xc_domaininfo_t info;
  2.1030 -        libxl_event event;
  2.1031 -        libxl_device_disk disk;
  2.1032 -        memset(&info, 0x00, sizeof(xc_dominfo_t));
  2.1033 -
  2.1034 -        FD_ZERO(&rfds);
  2.1035 -        FD_SET(fd, &rfds);
  2.1036 -
  2.1037 -        ret = select(fd + 1, &rfds, NULL, NULL, NULL);
  2.1038 -        if (!ret)
  2.1039 -            continue;
  2.1040 -        libxl_get_event(&ctx, &event);
  2.1041 -        switch (event.type) {
  2.1042 -            case DOMAIN_DEATH:
  2.1043 -                if (libxl_event_get_domain_death_info(&ctx, domid, &event, &info)) {
  2.1044 -                    LOG("Domain %d is dead", domid);
  2.1045 -                    if (info.flags & XEN_DOMINF_dying || (info.flags & XEN_DOMINF_shutdown && (((info.flags >> XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask) != SHUTDOWN_suspend))) {
  2.1046 -                        LOG("Domain %d needs to be clean: destroying the domain", domid);
  2.1047 -                        libxl_domain_destroy(&ctx, domid, 0);
  2.1048 -                        if (info.flags & XEN_DOMINF_shutdown &&
  2.1049 -                            (((info.flags >> XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask) == SHUTDOWN_reboot)) {
  2.1050 -                            libxl_free_waiter(w1);
  2.1051 -                            libxl_free_waiter(w2);
  2.1052 -                            free(w1);
  2.1053 -                            free(w2);
  2.1054 -                            LOG("Done. Rebooting now");
  2.1055 -                            goto start;
  2.1056 -                        }
  2.1057 -                        LOG("Done. Exiting now");
  2.1058 -                    }
  2.1059 -                    LOG("Domain %d does not need to be clean, exiting now", domid);
  2.1060 -                    exit(0);
  2.1061 -                }
  2.1062 -                break;
  2.1063 -            case DISK_EJECT:
  2.1064 -                if (libxl_event_get_disk_eject_info(&ctx, domid, &event, &disk))
  2.1065 -                    libxl_cdrom_insert(&ctx, domid, &disk);
  2.1066 -                break;
  2.1067 -        }
  2.1068 -        libxl_free_event(&event);
  2.1069 -    }
  2.1070 -
  2.1071 -    close(logfile);
  2.1072 -    exit(0);
  2.1073 -}
  2.1074 -
  2.1075 -static void help(char *command)
  2.1076 -{
  2.1077 -    if (!command || !strcmp(command, "help")) {
  2.1078 -        printf("Usage xl <subcommand> [args]\n\n");
  2.1079 -        printf("xl full list of subcommands:\n\n");
  2.1080 -        printf(" create                        create a domain from config file <filename>\n\n");
  2.1081 -        printf(" list                          list information about all domains\n\n");
  2.1082 -        printf(" destroy                       terminate a domain immediately\n\n");
  2.1083 -        printf(" pci-attach                    insert a new pass-through pci device\n\n");
  2.1084 -        printf(" pci-detach                    remove a domain's pass-through pci device\n\n");
  2.1085 -        printf(" pci-list                      list pass-through pci devices for a domain\n\n");
  2.1086 -        printf(" pause                         pause execution of a domain\n\n");
  2.1087 -        printf(" unpause                       unpause a paused domain\n\n");
  2.1088 -        printf(" console                       attach to domain's console\n\n");
  2.1089 -        printf(" save                          save a domain state to restore later\n\n");
  2.1090 -        printf(" restore                       restore a domain from a saved state\n\n");
  2.1091 -        printf(" cd-insert                     insert a cdrom into a guest's cd drive\n\n");
  2.1092 -        printf(" cd-eject                      eject a cdrom from a guest's cd drive\n\n");
  2.1093 -        printf(" mem-set                       set the current memory usage for a domain\n\n");
  2.1094 -        printf(" button-press                  indicate an ACPI button press to the domain\n\n");
  2.1095 -        printf(" vcpu-list                     list the VCPUs for all/some domains.\n\n");
  2.1096 -        printf(" vcpu-pin                      Set which CPUs a VCPU can use.\n\n");
  2.1097 -        printf(" vcpu-set                      Set the number of active VCPUs allowed for the domain.\n\n");
  2.1098 -        printf(" sched-credit                  Get/set credit scheduler parameters.\n\n");
  2.1099 -    } else if(!strcmp(command, "create")) {
  2.1100 -        printf("Usage: xl create <ConfigFile> [options] [vars]\n\n");
  2.1101 -        printf("Create a domain based on <ConfigFile>.\n\n");
  2.1102 -        printf("Options:\n\n");
  2.1103 -        printf("-h                     Print this help.\n");
  2.1104 -        printf("-p                     Leave the domain paused after it is created.\n");
  2.1105 -        printf("-d                     Enable debug messages.\n");
  2.1106 -        printf("-e                     Do not wait in the background for the death of the domain.\n");
  2.1107 -    } else if(!strcmp(command, "list")) {
  2.1108 -        printf("Usage: xl list [-v] [Domain]\n\n");
  2.1109 -        printf("List information about all/some domains.\n\n");
  2.1110 -    } else if(!strcmp(command, "pci-attach")) {
  2.1111 -        printf("Usage: xl pci-attach <Domain> <BDF> [Virtual Slot]\n\n");
  2.1112 -        printf("Insert a new pass-through pci device.\n\n");
  2.1113 -    } else if(!strcmp(command, "pci-detach")) {
  2.1114 -        printf("Usage: xl pci-detach <Domain> <BDF>\n\n");
  2.1115 -        printf("Remove a domain's pass-through pci device.\n\n");
  2.1116 -    } else if(!strcmp(command, "pci-list")) {
  2.1117 -        printf("Usage: xl pci-list <Domain>\n\n");
  2.1118 -        printf("List pass-through pci devices for a domain.\n\n");
  2.1119 -    } else if(!strcmp(command, "pause")) {
  2.1120 -        printf("Usage: xl pause <Domain>\n\n");
  2.1121 -        printf("Pause execution of a domain.\n\n");
  2.1122 -    } else if(!strcmp(command, "unpause")) {
  2.1123 -        printf("Usage: xl unpause <Domain>\n\n");
  2.1124 -        printf("Unpause a paused domain.\n\n");
  2.1125 -    } else if(!strcmp(command, "save")) {
  2.1126 -        printf("Usage: xl save [options] <Domain> <CheckpointFile> [<ConfigFile>]\n\n");
  2.1127 -        printf("Save a domain state to restore later.\n\n");
  2.1128 -        printf("Options:\n\n");
  2.1129 -        printf("-h                     Print this help.\n");
  2.1130 -        printf("-c                     Leave domain running after creating the snapshot.\n");
  2.1131 -    } else if(!strcmp(command, "restore")) {
  2.1132 -        printf("Usage: xl restore [options] [<ConfigFile>] <CheckpointFile>\n\n");
  2.1133 -        printf("Restore a domain from a saved state.\n\n");
  2.1134 -        printf("Options:\n\n");
  2.1135 -        printf("-h                     Print this help.\n");
  2.1136 -        printf("-p                     Do not unpause domain after restoring it.\n");
  2.1137 -        printf("-e                     Do not wait in the background for the death of the domain.\n");
  2.1138 -        printf("-d                     Enable debug messages.\n");
  2.1139 -    } else if(!strcmp(command, "migrate")) {
  2.1140 -        printf("Usage: xl migrate [options] <Domain> <host>\n\n");
  2.1141 -        printf("Save a domain state to restore later.\n\n");
  2.1142 -        printf("Options:\n\n");
  2.1143 -        printf("-h                     Print this help.\n");
  2.1144 -        printf("-C <config>            Send <config> instead of config file from creation.\n");
  2.1145 -        printf("-s <sshcommand>        Use <sshcommand> instead of ssh.  String will be passed to sh.  If empty, run <host> instead of ssh <host> xl migrate-receive [-d -e]\n");
  2.1146 -        printf("-e                     Do not wait in the background (on <host>) for the death of the domain.\n");
  2.1147 -    } else if(!strcmp(command, "migrate-receive")) {
  2.1148 -        printf("Usage: xl migrate-receive  - for internal use only");
  2.1149 -    } else if(!strcmp(command, "restore")) {
  2.1150 -        printf("Usage: xl restore [options] [<ConfigFile>] <CheckpointFile>\n\n");
  2.1151 -        printf("Restore a domain from a saved state.\n\n");
  2.1152 -        printf("Options:\n\n");
  2.1153 -        printf("-h                     Print this help.\n");
  2.1154 -        printf("-O                     Old (configless) xl save format.\n");
  2.1155 -        printf("-p                     Do not unpause domain after restoring it.\n");
  2.1156 -        printf("-e                     Do not wait in the background for the death of the domain.\n");
  2.1157 -    } else if(!strcmp(command, "destroy")) {
  2.1158 -        printf("Usage: xl destroy <Domain>\n\n");
  2.1159 -        printf("Terminate a domain immediately.\n\n");
  2.1160 -    } else if (!strcmp(command, "console")) {
  2.1161 -        printf("Usage: xl console <Domain>\n\n");
  2.1162 -        printf("Attach to domain's console.\n\n");
  2.1163 -    } else if (!strcmp(command, "cd-insert")) {
  2.1164 -        printf("Usage: xl cd-insert <Domain> <VirtualDevice> <type:path>\n\n");
  2.1165 -        printf("Insert a cdrom into a guest's cd drive.\n\n");
  2.1166 -    } else if (!strcmp(command, "cd-eject")) {
  2.1167 -        printf("Usage: xl cd-eject <Domain> <VirtualDevice>\n\n");
  2.1168 -        printf("Eject a cdrom from a guest's cd drive.\n\n");
  2.1169 -    } else if (!strcmp(command, "mem-set")) {
  2.1170 -        printf("Usage: xl mem-set <Domain> <MemKB>\n\n");
  2.1171 -        printf("Set the current memory usage for a domain.\n\n");
  2.1172 -    } else if (!strcmp(command, "button-press")) {
  2.1173 -        printf("Usage: xl button-press <Domain> <Button>\n\n");
  2.1174 -        printf("Indicate <Button> press to a domain.\n");
  2.1175 -        printf("<Button> may be 'power' or 'sleep'.\n\n");
  2.1176 -    } else if (!strcmp(command, "vcpu-list")) {
  2.1177 -        printf("Usage: xl vcpu-list [Domain, ...]\n\n");
  2.1178 -        printf("List the VCPUs for all/some domains.\n\n");
  2.1179 -    } else if (!strcmp(command, "vcpu-pin")) {
  2.1180 -        printf("Usage: xl vcpu-pin <Domain> <VCPU|all> <CPUs|all>\n\n");
  2.1181 -        printf("Set which CPUs a VCPU can use.\n\n");
  2.1182 -    } else if (!strcmp(command, "vcpu-set")) {
  2.1183 -        printf("Usage: xl vcpu-set <Domain> <vCPUs>\n\n");
  2.1184 -        printf("Set the number of active VCPUs for allowed for the domain.\n\n");
  2.1185 -    } else if (!strcmp(command, "sched-credit")) {
  2.1186 -        printf("Usage: xl sched-credit [-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]\n\n");
  2.1187 -        printf("Get/set credit scheduler parameters.\n");
  2.1188 -        printf("  -d DOMAIN, --domain=DOMAIN     Domain to modify\n");
  2.1189 -        printf("  -w WEIGHT, --weight=WEIGHT     Weight (int)\n");
  2.1190 -        printf("  -c CAP, --cap=CAP              Cap (int)\n");
  2.1191 -    }
  2.1192 -}
  2.1193 -
  2.1194 -void set_memory_target(char *p, char *mem)
  2.1195 -{
  2.1196 -    char *endptr;
  2.1197 -    uint32_t memorykb;
  2.1198 -
  2.1199 -    find_domain(p);
  2.1200 -
  2.1201 -    memorykb = strtoul(mem, &endptr, 10);
  2.1202 -    if (*endptr != '\0') {
  2.1203 -        fprintf(stderr, "invalid memory size: %s\n", mem);
  2.1204 -        exit(3);
  2.1205 -    }
  2.1206 -    printf("setting domid %d memory to : %d\n", domid, memorykb);
  2.1207 -    libxl_set_memory_target(&ctx, domid, memorykb);
  2.1208 -}
  2.1209 -
  2.1210 -int main_memset(int argc, char **argv)
  2.1211 -{
  2.1212 -    int opt = 0;
  2.1213 -    char *p = NULL, *mem;
  2.1214 -
  2.1215 -    while ((opt = getopt(argc, argv, "h:")) != -1) {
  2.1216 -        switch (opt) {
  2.1217 -        case 'h':
  2.1218 -            help("mem-set");
  2.1219 -            exit(0);
  2.1220 -        default:
  2.1221 -            fprintf(stderr, "option not supported\n");
  2.1222 -            break;
  2.1223 -        }
  2.1224 -    }
  2.1225 -    if (optind >= argc - 1) {
  2.1226 -        help("mem-set");
  2.1227 -        exit(2);
  2.1228 -    }
  2.1229 -
  2.1230 -    p = argv[optind];
  2.1231 -    mem = argv[optind + 1];
  2.1232 -
  2.1233 -    set_memory_target(p, mem);
  2.1234 -    exit(0);
  2.1235 -}
  2.1236 -
  2.1237 -void console(char *p, int cons_num)
  2.1238 -{
  2.1239 -    find_domain(p);
  2.1240 -    libxl_console_attach(&ctx, domid, cons_num);
  2.1241 -}
  2.1242 -
  2.1243 -void cd_insert(char *dom, char *virtdev, char *phys)
  2.1244 -{
  2.1245 -    libxl_device_disk disk;
  2.1246 -    char *p;
  2.1247 -
  2.1248 -    find_domain(dom);
  2.1249 -
  2.1250 -    disk.backend_domid = 0;
  2.1251 -    disk.domid = domid;
  2.1252 -    if (phys) {
  2.1253 -        p = strchr(phys, ':');
  2.1254 -        if (!p) {
  2.1255 -            fprintf(stderr, "No type specified, ");
  2.1256 -            disk.physpath = phys;
  2.1257 -            if (!strncmp(phys, "/dev", 4)) {
  2.1258 -                fprintf(stderr, "assuming phy:\n");
  2.1259 -                disk.phystype = PHYSTYPE_PHY;
  2.1260 -            } else {
  2.1261 -                fprintf(stderr, "assuming file:\n");
  2.1262 -                disk.phystype = PHYSTYPE_FILE;
  2.1263 -            }
  2.1264 -        } else {
  2.1265 -            *p = '\0';
  2.1266 -            p++;
  2.1267 -            disk.physpath = p;
  2.1268 -            libxl_string_to_phystype(&ctx, phys, &disk.phystype);
  2.1269 -        }
  2.1270 -    } else {
  2.1271 -            disk.physpath = NULL;
  2.1272 -            disk.phystype = 0;
  2.1273 -    }
  2.1274 -    disk.virtpath = virtdev;
  2.1275 -    disk.unpluggable = 1;
  2.1276 -    disk.readwrite = 0;
  2.1277 -    disk.is_cdrom = 1;
  2.1278 -
  2.1279 -    libxl_cdrom_insert(&ctx, domid, &disk);
  2.1280 -}
  2.1281 -
  2.1282 -int main_cd_eject(int argc, char **argv)
  2.1283 -{
  2.1284 -    int opt = 0;
  2.1285 -    char *p = NULL, *virtdev;
  2.1286 -
  2.1287 -    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  2.1288 -        switch (opt) {
  2.1289 -        case 'h':
  2.1290 -            help("cd-eject");
  2.1291 -            exit(0);
  2.1292 -        default:
  2.1293 -            fprintf(stderr, "option not supported\n");
  2.1294 -            break;
  2.1295 -        }
  2.1296 -    }
  2.1297 -    if (optind >= argc - 1) {
  2.1298 -        help("cd-eject");
  2.1299 -        exit(2);
  2.1300 -    }
  2.1301 -
  2.1302 -    p = argv[optind];
  2.1303 -    virtdev = argv[optind + 1];
  2.1304 -
  2.1305 -    cd_insert(p, virtdev, NULL);
  2.1306 -    exit(0);
  2.1307 -}
  2.1308 -
  2.1309 -int main_cd_insert(int argc, char **argv)
  2.1310 -{
  2.1311 -    int opt = 0;
  2.1312 -    char *p = NULL, *file = NULL, *virtdev;
  2.1313 -
  2.1314 -    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  2.1315 -        switch (opt) {
  2.1316 -        case 'h':
  2.1317 -            help("cd-insert");
  2.1318 -            exit(0);
  2.1319 -        default:
  2.1320 -            fprintf(stderr, "option not supported\n");
  2.1321 -            break;
  2.1322 -        }
  2.1323 -    }
  2.1324 -    if (optind >= argc - 2) {
  2.1325 -        help("cd-insert");
  2.1326 -        exit(2);
  2.1327 -    }
  2.1328 -
  2.1329 -    p = argv[optind];
  2.1330 -    virtdev = argv[optind + 1];
  2.1331 -    file = argv[optind + 2];
  2.1332 -
  2.1333 -    cd_insert(p, virtdev, file);
  2.1334 -    exit(0);
  2.1335 -}
  2.1336 -
  2.1337 -int main_console(int argc, char **argv)
  2.1338 -{
  2.1339 -    int opt = 0, cons_num = 0;
  2.1340 -    char *p = NULL;
  2.1341 -
  2.1342 -    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  2.1343 -        switch (opt) {
  2.1344 -        case 'h':
  2.1345 -            help("console");
  2.1346 -            exit(0);
  2.1347 -        case 'n':
  2.1348 -            if (optarg) {
  2.1349 -                cons_num = strtol(optarg, NULL, 10);
  2.1350 -            }
  2.1351 -            break;
  2.1352 -        default:
  2.1353 -            fprintf(stderr, "option not supported\n");
  2.1354 -            break;
  2.1355 -        }
  2.1356 -    }
  2.1357 -    if (optind >= argc) {
  2.1358 -        help("console");
  2.1359 -        exit(2);
  2.1360 -    }
  2.1361 -
  2.1362 -    p = argv[optind];
  2.1363 -
  2.1364 -    console(p, cons_num);
  2.1365 -    exit(0);
  2.1366 -}
  2.1367 -
  2.1368 -void pcilist(char *dom)
  2.1369 -{
  2.1370 -    libxl_device_pci *pcidevs;
  2.1371 -    int num, i;
  2.1372 -
  2.1373 -    find_domain(dom);
  2.1374 -
  2.1375 -    pcidevs = libxl_device_pci_list(&ctx, domid, &num);
  2.1376 -    if (!num)
  2.1377 -        return;
  2.1378 -    printf("VFn  domain bus  slot func\n");
  2.1379 -    for (i = 0; i < num; i++) {
  2.1380 -        printf("0x%02x 0x%04x 0x%02x 0x%02x 0x%01x\n", pcidevs[i].vdevfn, pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
  2.1381 -    }
  2.1382 -    free(pcidevs);
  2.1383 -}
  2.1384 -
  2.1385 -int main_pcilist(int argc, char **argv)
  2.1386 -{
  2.1387 -    int opt;
  2.1388 -    char *domname = NULL;
  2.1389 -
  2.1390 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.1391 -        switch (opt) {
  2.1392 -        case 'h':
  2.1393 -            help("pci-list");
  2.1394 -            exit(0);
  2.1395 -        default:
  2.1396 -            fprintf(stderr, "option not supported\n");
  2.1397 -            break;
  2.1398 -        }
  2.1399 -    }
  2.1400 -    if (optind >= argc) {
  2.1401 -        help("pci-list");
  2.1402 -        exit(2);
  2.1403 -    }
  2.1404 -
  2.1405 -    domname = argv[optind];
  2.1406 -
  2.1407 -    pcilist(domname);
  2.1408 -    exit(0);
  2.1409 -}
  2.1410 -
  2.1411 -void pcidetach(char *dom, char *bdf)
  2.1412 -{
  2.1413 -    libxl_device_pci pcidev;
  2.1414 -    unsigned int domain, bus, dev, func;
  2.1415 -
  2.1416 -    find_domain(dom);
  2.1417 -
  2.1418 -    memset(&pcidev, 0x00, sizeof(pcidev));
  2.1419 -    sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func);
  2.1420 -    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
  2.1421 -    libxl_device_pci_remove(&ctx, domid, &pcidev);
  2.1422 -}
  2.1423 -
  2.1424 -int main_pcidetach(int argc, char **argv)
  2.1425 -{
  2.1426 -    int opt;
  2.1427 -    char *domname = NULL, *bdf = NULL;
  2.1428 -
  2.1429 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.1430 -        switch (opt) {
  2.1431 -        case 'h':
  2.1432 -            help("pci-attach");
  2.1433 -            exit(0);
  2.1434 -        default:
  2.1435 -            fprintf(stderr, "option not supported\n");
  2.1436 -            break;
  2.1437 -        }
  2.1438 -    }
  2.1439 -    if (optind >= argc - 1) {
  2.1440 -        help("pci-detach");
  2.1441 -        exit(2);
  2.1442 -    }
  2.1443 -
  2.1444 -    domname = argv[optind];
  2.1445 -    bdf = argv[optind + 1];
  2.1446 -
  2.1447 -    pcidetach(domname, bdf);
  2.1448 -    exit(0);
  2.1449 -}
  2.1450 -void pciattach(char *dom, char *bdf, char *vs)
  2.1451 -{
  2.1452 -    libxl_device_pci pcidev;
  2.1453 -    unsigned int domain, bus, dev, func;
  2.1454 -
  2.1455 -    find_domain(dom);
  2.1456 -
  2.1457 -    memset(&pcidev, 0x00, sizeof(pcidev));
  2.1458 -    sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func);
  2.1459 -    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
  2.1460 -    libxl_device_pci_add(&ctx, domid, &pcidev);
  2.1461 -}
  2.1462 -
  2.1463 -int main_pciattach(int argc, char **argv)
  2.1464 -{
  2.1465 -    int opt;
  2.1466 -    char *domname = NULL, *bdf = NULL, *vs = NULL;
  2.1467 -
  2.1468 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.1469 -        switch (opt) {
  2.1470 -        case 'h':
  2.1471 -            help("pci-attach");
  2.1472 -            exit(0);
  2.1473 -        default:
  2.1474 -            fprintf(stderr, "option not supported\n");
  2.1475 -            break;
  2.1476 -        }
  2.1477 -    }
  2.1478 -    if (optind >= argc - 1) {
  2.1479 -        help("pci-attach");
  2.1480 -        exit(2);
  2.1481 -    }
  2.1482 -
  2.1483 -    domname = argv[optind];
  2.1484 -    bdf = argv[optind + 1];
  2.1485 -
  2.1486 -    if (optind + 1 < argc)
  2.1487 -        vs = argv[optind + 2];
  2.1488 -
  2.1489 -    pciattach(domname, bdf, vs);
  2.1490 -    exit(0);
  2.1491 -}
  2.1492 -
  2.1493 -void pause_domain(char *p)
  2.1494 -{
  2.1495 -    find_domain(p);
  2.1496 -    libxl_domain_pause(&ctx, domid);
  2.1497 -}
  2.1498 -
  2.1499 -void unpause_domain(char *p)
  2.1500 -{
  2.1501 -    find_domain(p);
  2.1502 -    libxl_domain_unpause(&ctx, domid);
  2.1503 -}
  2.1504 -
  2.1505 -void destroy_domain(char *p)
  2.1506 -{
  2.1507 -    int rc;
  2.1508 -    find_domain(p);
  2.1509 -    rc = libxl_domain_destroy(&ctx, domid, 0);
  2.1510 -    if (rc) { fprintf(stderr,"destroy failed (rc=%d)\n.",rc); exit(-1); }
  2.1511 -}
  2.1512 -
  2.1513 -void list_domains(int verbose)
  2.1514 -{
  2.1515 -    struct libxl_dominfo *info;
  2.1516 -    int nb_domain, i;
  2.1517 -
  2.1518 -    info = libxl_list_domain(&ctx, &nb_domain);
  2.1519 -
  2.1520 -    if (!info) {
  2.1521 -        fprintf(stderr, "libxl_domain_infolist failed.\n");
  2.1522 -        exit(1);
  2.1523 -    }
  2.1524 -    printf("Name                                        ID   Mem VCPUs\tState\tTime(s)\n");
  2.1525 -    for (i = 0; i < nb_domain; i++) {
  2.1526 -        printf("%-40s %5d %5lu %5d        %c%c%c %8.1f",
  2.1527 -                libxl_domid_to_name(&ctx, info[i].domid),
  2.1528 -                info[i].domid,
  2.1529 -                (unsigned long) (info[i].max_memkb / 1024),
  2.1530 -                info[i].vcpu_online,
  2.1531 -                info[i].running ? 'r' : '-',
  2.1532 -                info[i].paused ? 'p' : '-',
  2.1533 -                info[i].dying ? 'd' : '-',
  2.1534 -                ((float)info[i].cpu_time / 1e9));
  2.1535 -        if (verbose) {
  2.1536 -            char *uuid = libxl_uuid2string(&ctx, info[i].uuid);
  2.1537 -            printf(" %s", uuid);
  2.1538 -        }
  2.1539 -        putchar('\n');
  2.1540 -    }
  2.1541 -    free(info);
  2.1542 -}
  2.1543 -
  2.1544 -void list_vm(void)
  2.1545 -{
  2.1546 -    struct libxl_vminfo *info;
  2.1547 -    int nb_vm, i;
  2.1548 -
  2.1549 -    info = libxl_list_vm(&ctx, &nb_vm);
  2.1550 -
  2.1551 -    if (info < 0) {
  2.1552 -        fprintf(stderr, "libxl_domain_infolist failed.\n");
  2.1553 -        exit(1);
  2.1554 -    }
  2.1555 -    printf("UUID                                  ID    name\n");
  2.1556 -    for (i = 0; i < nb_vm; i++) {
  2.1557 -        printf(UUID_FMT "  %d    %-30s\n",
  2.1558 -            info[i].uuid[0], info[i].uuid[1], info[i].uuid[2], info[i].uuid[3],
  2.1559 -            info[i].uuid[4], info[i].uuid[5], info[i].uuid[6], info[i].uuid[7],
  2.1560 -            info[i].uuid[8], info[i].uuid[9], info[i].uuid[10], info[i].uuid[11],
  2.1561 -            info[i].uuid[12], info[i].uuid[13], info[i].uuid[14], info[i].uuid[15],
  2.1562 -            info[i].domid, libxl_domid_to_name(&ctx, info[i].domid));
  2.1563 -    }
  2.1564 -    free(info);
  2.1565 -}
  2.1566 -
  2.1567 -static void save_domain_core_begin(char *domain_spec,
  2.1568 -                                   const char *override_config_file,
  2.1569 -                                   uint8_t **config_data_r,
  2.1570 -                                   int *config_len_r)
  2.1571 -{
  2.1572 -    int rc;
  2.1573 -
  2.1574 -    find_domain(domain_spec);
  2.1575 -
  2.1576 -    /* configuration file in optional data: */
  2.1577 -
  2.1578 -    if (override_config_file) {
  2.1579 -        void *config_v = 0;
  2.1580 -        rc = libxl_read_file_contents(&ctx, override_config_file,
  2.1581 -                                      &config_v, config_len_r);
  2.1582 -        *config_data_r = config_v;
  2.1583 -    } else {
  2.1584 -        rc = libxl_userdata_retrieve(&ctx, domid, "xl",
  2.1585 -                                     config_data_r, config_len_r);
  2.1586 -    }
  2.1587 -    if (rc) {
  2.1588 -        fputs("Unable to get config file\n",stderr);
  2.1589 -        exit(2);
  2.1590 -    }
  2.1591 -}
  2.1592 -
  2.1593 -void save_domain_core_writeconfig(int fd, const char *filename,
  2.1594 -                                  const uint8_t *config_data, int config_len)
  2.1595 -{
  2.1596 -    struct save_file_header hdr;
  2.1597 -    uint8_t *optdata_begin;
  2.1598 -    union { uint32_t u32; char b[4]; } u32buf;
  2.1599 -
  2.1600 -    memset(&hdr, 0, sizeof(hdr));
  2.1601 -    memcpy(hdr.magic, savefileheader_magic, sizeof(hdr.magic));
  2.1602 -    hdr.byteorder = SAVEFILE_BYTEORDER_VALUE;
  2.1603 -
  2.1604 -    optdata_begin= 0;
  2.1605 -
  2.1606 -#define ADD_OPTDATA(ptr, len) ({                                            \
  2.1607 -    if ((len)) {                                                        \
  2.1608 -        hdr.optional_data_len += (len);                                 \
  2.1609 -        optdata_begin = xrealloc(optdata_begin, hdr.optional_data_len); \
  2.1610 -        memcpy(optdata_begin + hdr.optional_data_len - (len),           \
  2.1611 -               (ptr), (len));                                           \
  2.1612 -    }                                                                   \
  2.1613 -                          })
  2.1614 -
  2.1615 -    u32buf.u32 = config_len;
  2.1616 -    ADD_OPTDATA(u32buf.b,    4);
  2.1617 -    ADD_OPTDATA(config_data, config_len);
  2.1618 -
  2.1619 -    /* that's the optional data */
  2.1620 -
  2.1621 -    CHK_ERRNO( libxl_write_exactly(&ctx, fd,
  2.1622 -        &hdr, sizeof(hdr), filename, "header") );
  2.1623 -    CHK_ERRNO( libxl_write_exactly(&ctx, fd,
  2.1624 -        optdata_begin, hdr.optional_data_len, filename, "header") );
  2.1625 -
  2.1626 -    fprintf(stderr, "Saving to %s new xl format (info"
  2.1627 -            " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n",
  2.1628 -            filename, hdr.mandatory_flags, hdr.optional_flags,
  2.1629 -            hdr.optional_data_len);
  2.1630 -}
  2.1631 -
  2.1632 -int save_domain(char *p, char *filename, int checkpoint,
  2.1633 -                const char *override_config_file)
  2.1634 -{
  2.1635 -    int fd;
  2.1636 -    uint8_t *config_data;
  2.1637 -    int config_len;
  2.1638 -
  2.1639 -    save_domain_core_begin(p, override_config_file, &config_data, &config_len);
  2.1640 -
  2.1641 -    if (!config_len) {
  2.1642 -        fputs(" Savefile will not contain xl domain config\n", stderr);
  2.1643 -    }
  2.1644 -
  2.1645 -    fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
  2.1646 -    if (fd < 0) {
  2.1647 -        fprintf(stderr, "Failed to open temp file %s for writing\n", filename);
  2.1648 -        exit(2);
  2.1649 -    }
  2.1650 -
  2.1651 -    save_domain_core_writeconfig(fd, filename, config_data, config_len);
  2.1652 -
  2.1653 -    libxl_domain_suspend(&ctx, NULL, domid, fd);
  2.1654 -    close(fd);
  2.1655 -
  2.1656 -    if (checkpoint)
  2.1657 -        libxl_domain_unpause(&ctx, domid);
  2.1658 -    else
  2.1659 -        libxl_domain_destroy(&ctx, domid, 0);
  2.1660 -
  2.1661 -    exit(0);
  2.1662 -}
  2.1663 -
  2.1664 -static int migrate_read_fixedmessage(int fd, const void *msg, int msgsz,
  2.1665 -                                     const char *what, const char *rune) {
  2.1666 -    char buf[msgsz];
  2.1667 -    const char *stream;
  2.1668 -    int rc;
  2.1669 -
  2.1670 -    stream = rune ? "migration receiver stream" : "migration stream";
  2.1671 -    rc = libxl_read_exactly(&ctx, fd, buf, msgsz, stream, what);
  2.1672 -    if (rc) return ERROR_FAIL;
  2.1673 -
  2.1674 -    if (memcmp(buf, msg, msgsz)) {
  2.1675 -        fprintf(stderr, "%s contained unexpected data instead of %s\n",
  2.1676 -                stream, what);
  2.1677 -        if (rune)
  2.1678 -            fprintf(stderr, "(command run was: %s )\n", rune);
  2.1679 -        return ERROR_FAIL;
  2.1680 -    }
  2.1681 -    return 0;
  2.1682 -}
  2.1683 -
  2.1684 -static void migration_child_report(pid_t migration_child, int recv_fd) {
  2.1685 -    pid_t child;
  2.1686 -    int status, sr;
  2.1687 -    struct timeval now, waituntil, timeout;
  2.1688 -    static const struct timeval pollinterval = { 0, 1000 }; /* 1ms */
  2.1689 -
  2.1690 -    if (!migration_child) return;
  2.1691 -
  2.1692 -    CHK_ERRNO( gettimeofday(&waituntil, 0) );
  2.1693 -    waituntil.tv_sec += 2;
  2.1694 -
  2.1695 -    for (;;) {
  2.1696 -        child = waitpid(migration_child, &status, WNOHANG);
  2.1697 -
  2.1698 -        if (child == migration_child) {
  2.1699 -            if (status)
  2.1700 -                libxl_report_child_exitstatus(&ctx, XL_LOG_INFO,
  2.1701 -                                              "migration target process",
  2.1702 -                                              migration_child, status);
  2.1703 -            break;
  2.1704 -        }
  2.1705 -        if (child == -1) {
  2.1706 -            if (errno == EINTR) continue;
  2.1707 -            fprintf(stderr, "wait for migration child [%ld] failed: %s\n",
  2.1708 -                    (long)migration_child, strerror(errno));
  2.1709 -            break;
  2.1710 -        }
  2.1711 -        assert(child == 0);
  2.1712 -
  2.1713 -        CHK_ERRNO( gettimeofday(&now, 0) );
  2.1714 -        if (timercmp(&now, &waituntil, >)) {
  2.1715 -            fprintf(stderr, "migration child [%ld] not exiting, no longer"
  2.1716 -                    " waiting (exit status will be unreported)\n",
  2.1717 -                    (long)migration_child);
  2.1718 -            break;
  2.1719 -        }
  2.1720 -        timersub(&waituntil, &now, &timeout);
  2.1721 -
  2.1722 -        if (recv_fd >= 0) {
  2.1723 -            fd_set readfds, exceptfds;
  2.1724 -            FD_ZERO(&readfds);
  2.1725 -            FD_ZERO(&exceptfds);
  2.1726 -            FD_SET(recv_fd, &readfds);
  2.1727 -            FD_SET(recv_fd, &exceptfds);
  2.1728 -            sr = select(recv_fd+1, &readfds,0,&exceptfds, &timeout);
  2.1729 -        } else {
  2.1730 -            if (timercmp(&timeout, &pollinterval, >))
  2.1731 -                timeout = pollinterval;
  2.1732 -            sr = select(0,0,0,0, &timeout);
  2.1733 -        }
  2.1734 -        if (sr > 0) {
  2.1735 -            recv_fd = -1;
  2.1736 -        } else if (sr == 0) {
  2.1737 -        } else if (sr == -1) {
  2.1738 -            if (errno != EINTR) {
  2.1739 -                fprintf(stderr, "migration child [%ld] exit wait select"
  2.1740 -                        " failed unexpectedly: %s\n",
  2.1741 -                        (long)migration_child, strerror(errno));
  2.1742 -                break;
  2.1743 -            }
  2.1744 -        }
  2.1745 -    }
  2.1746 -    migration_child = 0;
  2.1747 -}
  2.1748 -
  2.1749 -static void migrate_domain(char *domain_spec, const char *rune,
  2.1750 -                           const char *override_config_file)
  2.1751 -{
  2.1752 -    pid_t child = -1;
  2.1753 -    int rc;
  2.1754 -    int sendpipe[2], recvpipe[2];
  2.1755 -    int send_fd, recv_fd;
  2.1756 -    libxl_domain_suspend_info suspinfo;
  2.1757 -    char *away_domname;
  2.1758 -    char rc_buf;
  2.1759 -    uint8_t *config_data;
  2.1760 -    int config_len;
  2.1761 -
  2.1762 -    save_domain_core_begin(domain_spec, override_config_file,
  2.1763 -                           &config_data, &config_len);
  2.1764 -
  2.1765 -    if (!common_domname) {
  2.1766 -        common_domname = libxl_domid_to_name(&ctx, domid);
  2.1767 -        /* libxl_domid_to_name fails ?  don't bother with names then */
  2.1768 -    }
  2.1769 -
  2.1770 -    if (!config_len) {
  2.1771 -        fprintf(stderr, "No config file stored for running domain and "
  2.1772 -                "none supplied - cannot migrate.\n");
  2.1773 -        exit(1);
  2.1774 -    }
  2.1775 -
  2.1776 -    MUST( libxl_pipe(&ctx, sendpipe) );
  2.1777 -    MUST( libxl_pipe(&ctx, recvpipe) );
  2.1778 -
  2.1779 -    child = libxl_fork(&ctx);
  2.1780 -    if (child==-1) exit(1);
  2.1781 -
  2.1782 -    if (!child) {
  2.1783 -        dup2(sendpipe[0], 0);
  2.1784 -        dup2(recvpipe[1], 1);
  2.1785 -        close(sendpipe[0]); close(sendpipe[1]);
  2.1786 -        close(recvpipe[0]); close(recvpipe[1]);
  2.1787 -        execlp("sh","sh","-c",rune,(char*)0);
  2.1788 -        perror("failed to exec sh");
  2.1789 -        exit(-1);
  2.1790 -    }
  2.1791 -
  2.1792 -    close(sendpipe[0]);
  2.1793 -    close(recvpipe[1]);
  2.1794 -    send_fd = sendpipe[1];
  2.1795 -    recv_fd = recvpipe[0];
  2.1796 -
  2.1797 -    signal(SIGPIPE, SIG_IGN);
  2.1798 -    /* if receiver dies, we get an error and can clean up
  2.1799 -       rather than just dying */
  2.1800 -
  2.1801 -    rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_banner,
  2.1802 -                                   sizeof(migrate_receiver_banner)-1,
  2.1803 -                                   "banner", rune);
  2.1804 -    if (rc) {
  2.1805 -        close(send_fd);
  2.1806 -        migration_child_report(child, recv_fd);
  2.1807 -        exit(-rc);
  2.1808 -    }
  2.1809 -
  2.1810 -    save_domain_core_writeconfig(send_fd, "migration stream",
  2.1811 -                                 config_data, config_len);
  2.1812 -
  2.1813 -    memset(&suspinfo, 0, sizeof(suspinfo));
  2.1814 -    suspinfo.flags |= XL_SUSPEND_LIVE;
  2.1815 -    rc = libxl_domain_suspend(&ctx, &suspinfo, domid, send_fd);
  2.1816 -    if (rc) {
  2.1817 -        fprintf(stderr, "migration sender: libxl_domain_suspend failed"
  2.1818 -                " (rc=%d)\n", rc);
  2.1819 -        goto failed_resume;
  2.1820 -    }
  2.1821 -
  2.1822 -    fprintf(stderr, "migration sender: Transfer complete.\n");
  2.1823 -
  2.1824 -    rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_ready,
  2.1825 -                                   sizeof(migrate_receiver_ready),
  2.1826 -                                   "ready message", rune);
  2.1827 -    if (rc) goto failed_resume;
  2.1828 -
  2.1829 -    /* right, at this point we are about give the destination
  2.1830 -     * permission to rename and resume, so we must first rename the
  2.1831 -     * domain away ourselves */
  2.1832 -
  2.1833 -    fprintf(stderr, "migration sender: Target has acknowledged transfer.\n");
  2.1834 -
  2.1835 -    if (common_domname) {
  2.1836 -        asprintf(&away_domname, "%s--migratedaway", common_domname);
  2.1837 -        rc = libxl_domain_rename(&ctx, domid,
  2.1838 -                                 common_domname, away_domname, 0);
  2.1839 -        if (rc) goto failed_resume;
  2.1840 -    }
  2.1841 -
  2.1842 -    /* point of no return - as soon as we have tried to say
  2.1843 -     * "go" to the receiver, it's not safe to carry on.  We leave
  2.1844 -     * the domain renamed to %s--migratedaway in case that's helpful.
  2.1845 -     */
  2.1846 -
  2.1847 -    fprintf(stderr, "migration sender: Giving target permission to start.\n");
  2.1848 -
  2.1849 -    rc = libxl_write_exactly(&ctx, send_fd,
  2.1850 -                             migrate_permission_to_go,
  2.1851 -                             sizeof(migrate_permission_to_go),
  2.1852 -                             "migration stream", "GO message");
  2.1853 -    if (rc) goto failed_badly;
  2.1854 -
  2.1855 -    rc = migrate_read_fixedmessage(recv_fd, migrate_report,
  2.1856 -                                   sizeof(migrate_report),
  2.1857 -                                   "success/failure report message", rune);
  2.1858 -    if (rc) goto failed_badly;
  2.1859 -
  2.1860 -    rc = libxl_read_exactly(&ctx, recv_fd,
  2.1861 -                            &rc_buf, 1,
  2.1862 -                            "migration ack stream", "success/failure status");
  2.1863 -    if (rc) goto failed_badly;
  2.1864 -
  2.1865 -    if (rc_buf) {
  2.1866 -        fprintf(stderr, "migration sender: Target reports startup failure"
  2.1867 -                " (status code %d).\n", rc_buf);
  2.1868 -
  2.1869 -        rc = migrate_read_fixedmessage(recv_fd, migrate_permission_to_go,
  2.1870 -                                       sizeof(migrate_permission_to_go),
  2.1871 -                                       "permission for sender to resume",
  2.1872 -                                       rune);
  2.1873 -        if (rc) goto failed_badly;
  2.1874 -
  2.1875 -        fprintf(stderr, "migration sender: Trying to resume at our end.\n");
  2.1876 -
  2.1877 -        if (common_domname) {
  2.1878 -            libxl_domain_rename(&ctx, domid,
  2.1879 -                                away_domname, common_domname, 0);
  2.1880 -        }
  2.1881 -        rc = libxl_domain_resume(&ctx, domid);
  2.1882 -        if (!rc) fprintf(stderr, "migration sender: Resumed OK.\n");
  2.1883 -
  2.1884 -        fprintf(stderr, "Migration failed due to problems at target.\n");
  2.1885 -        exit(-ERROR_FAIL);
  2.1886 -    }
  2.1887 -
  2.1888 -    fprintf(stderr, "migration sender: Target reports successful startup.\n");
  2.1889 -    libxl_domain_destroy(&ctx, domid, 1); /* bang! */
  2.1890 -    fprintf(stderr, "Migration successful.\n");
  2.1891 -    exit(0);
  2.1892 -
  2.1893 - failed_resume:
  2.1894 -    close(send_fd);
  2.1895 -    migration_child_report(child, recv_fd);
  2.1896 -    fprintf(stderr, "Migration failed, resuming at sender.\n");
  2.1897 -    libxl_domain_resume(&ctx, domid);
  2.1898 -    exit(-ERROR_FAIL);
  2.1899 -
  2.1900 - failed_badly:
  2.1901 -    fprintf(stderr,
  2.1902 - "** Migration failed during final handshake **\n"
  2.1903 - "Domain state is now undefined !\n"
  2.1904 - "Please CHECK AT BOTH ENDS for running instances, before renaming and\n"
  2.1905 - " resuming at most one instance.  Two simultaneous instances of the domain\n"
  2.1906 - " would probably result in SEVERE DATA LOSS and it is now your\n"
  2.1907 - " responsibility to avoid that.  Sorry.\n");
  2.1908 -
  2.1909 -    close(send_fd);
  2.1910 -    migration_child_report(child, recv_fd);
  2.1911 -    exit(-ERROR_BADFAIL);
  2.1912 -}
  2.1913 -
  2.1914 -static void migrate_receive(int debug, int daemonize)
  2.1915 -{
  2.1916 -    int rc, rc2;
  2.1917 -    char rc_buf;
  2.1918 -    char *migration_domname;
  2.1919 -
  2.1920 -    signal(SIGPIPE, SIG_IGN);
  2.1921 -    /* if we get SIGPIPE we'd rather just have it as an error */
  2.1922 -
  2.1923 -    fprintf(stderr, "migration target: Ready to receive domain.\n");
  2.1924 -
  2.1925 -    CHK_ERRNO( libxl_write_exactly(&ctx, 1,
  2.1926 -                                   migrate_receiver_banner,
  2.1927 -                                   sizeof(migrate_receiver_banner)-1,
  2.1928 -                                   "migration ack stream",
  2.1929 -                                   "banner") );
  2.1930 -
  2.1931 -    rc = create_domain(debug, daemonize,
  2.1932 -                       0 /* no config file, use incoming */,
  2.1933 -                       "incoming migration stream", 1,
  2.1934 -                       0, &migration_domname);
  2.1935 -    if (rc) {
  2.1936 -        fprintf(stderr, "migration target: Domain creation failed"
  2.1937 -                " (code %d).\n", rc);
  2.1938 -        exit(-rc);
  2.1939 -    }
  2.1940 -
  2.1941 -    fprintf(stderr, "migration target: Transfer complete,"
  2.1942 -            " requesting permission to start domain.\n");
  2.1943 -
  2.1944 -    rc = libxl_write_exactly(&ctx, 1,
  2.1945 -                             migrate_receiver_ready,
  2.1946 -                             sizeof(migrate_receiver_ready),
  2.1947 -                             "migration ack stream", "ready message");
  2.1948 -    if (rc) exit(-rc);
  2.1949 -
  2.1950 -    rc = migrate_read_fixedmessage(0, migrate_permission_to_go,
  2.1951 -                                   sizeof(migrate_permission_to_go),
  2.1952 -                                   "GO message", 0);
  2.1953 -    if (rc) goto perhaps_destroy_notify_rc;
  2.1954 -
  2.1955 -    fprintf(stderr, "migration target: Got permission, starting domain.\n");
  2.1956 -
  2.1957 -    if (migration_domname) {
  2.1958 -        rc = libxl_domain_rename(&ctx, domid,
  2.1959 -                                 migration_domname, common_domname, 0);
  2.1960 -        if (rc) goto perhaps_destroy_notify_rc;
  2.1961 -    }
  2.1962 -
  2.1963 -    rc = libxl_domain_unpause(&ctx, domid);
  2.1964 -    if (rc) goto perhaps_destroy_notify_rc;
  2.1965 -
  2.1966 -    fprintf(stderr, "migration target: Domain started successsfully.\n");
  2.1967 -    rc = 0;
  2.1968 -
  2.1969 - perhaps_destroy_notify_rc:
  2.1970 -    rc2 = libxl_write_exactly(&ctx, 1,
  2.1971 -                              migrate_report, sizeof(migrate_report),
  2.1972 -                              "migration ack stream",
  2.1973 -                              "success/failure report");
  2.1974 -    if (rc2) exit(-ERROR_BADFAIL);
  2.1975 -
  2.1976 -    rc_buf = -rc;
  2.1977 -    assert(!!rc_buf == !!rc);
  2.1978 -    rc2 = libxl_write_exactly(&ctx, 1, &rc_buf, 1,
  2.1979 -                              "migration ack stream",
  2.1980 -                              "success/failure code");
  2.1981 -    if (rc2) exit(-ERROR_BADFAIL);
  2.1982 -
  2.1983 -    if (rc) {
  2.1984 -        fprintf(stderr, "migration target: Failure, destroying our copy.\n");
  2.1985 -
  2.1986 -        rc2 = libxl_domain_destroy(&ctx, domid, 1);
  2.1987 -        if (rc2) {
  2.1988 -            fprintf(stderr, "migration target: Failed to destroy our copy"
  2.1989 -                    " (code %d).\n", rc2);
  2.1990 -            exit(-ERROR_BADFAIL);
  2.1991 -        }
  2.1992 -
  2.1993 -        fprintf(stderr, "migration target: Cleanup OK, granting sender"
  2.1994 -                " permission to resume.\n");
  2.1995 -
  2.1996 -        rc2 = libxl_write_exactly(&ctx, 1,
  2.1997 -                                  migrate_permission_to_go,
  2.1998 -                                  sizeof(migrate_permission_to_go),
  2.1999 -                                  "migration ack stream",
  2.2000 -                                  "permission to sender to have domain back");
  2.2001 -        if (rc2) exit(-ERROR_BADFAIL);
  2.2002 -    }
  2.2003 -
  2.2004 -    exit(0);
  2.2005 -}
  2.2006 -
  2.2007 -int main_restore(int argc, char **argv)
  2.2008 -{
  2.2009 -    char *checkpoint_file = NULL;
  2.2010 -    char *config_file = NULL;
  2.2011 -    int paused = 0, debug = 0, daemonize = 1;
  2.2012 -    int opt, rc;
  2.2013 -
  2.2014 -    while ((opt = getopt(argc, argv, "hpde")) != -1) {
  2.2015 -        switch (opt) {
  2.2016 -        case 'p':
  2.2017 -            paused = 1;
  2.2018 -            break;
  2.2019 -        case 'd':
  2.2020 -            debug = 1;
  2.2021 -            break;
  2.2022 -        case 'e':
  2.2023 -            daemonize = 0;
  2.2024 -            break;
  2.2025 -        case 'h':
  2.2026 -            help("restore");
  2.2027 -            exit(0);
  2.2028 -        default:
  2.2029 -            fprintf(stderr, "option not supported\n");
  2.2030 -            break;
  2.2031 -        }
  2.2032 -    }
  2.2033 -
  2.2034 -    if (argc-optind == 1) {
  2.2035 -        checkpoint_file = argv[optind];
  2.2036 -    } else if (argc-optind == 2) {
  2.2037 -        config_file = argv[optind];
  2.2038 -        checkpoint_file = argv[optind + 1];
  2.2039 -    } else {
  2.2040 -        help("restore");
  2.2041 -        exit(2);
  2.2042 -    }
  2.2043 -    rc = create_domain(debug, daemonize, config_file,
  2.2044 -                       checkpoint_file, paused, -1, 0);
  2.2045 -    exit(-rc);
  2.2046 -}
  2.2047 -
  2.2048 -int main_migrate_receive(int argc, char **argv)
  2.2049 -{
  2.2050 -    int debug = 0, daemonize = 1;
  2.2051 -    int opt;
  2.2052 -
  2.2053 -    while ((opt = getopt(argc, argv, "hed")) != -1) {
  2.2054 -        switch (opt) {
  2.2055 -        case 'h':
  2.2056 -            help("restore");
  2.2057 -            exit(2);
  2.2058 -            break;
  2.2059 -        case 'e':
  2.2060 -            daemonize = 0;
  2.2061 -            break;
  2.2062 -        case 'd':
  2.2063 -            debug = 1;
  2.2064 -            break;
  2.2065 -        default:
  2.2066 -            fprintf(stderr, "option not supported\n");
  2.2067 -            break;
  2.2068 -        }
  2.2069 -    }
  2.2070 -
  2.2071 -    if (argc-optind != 0) {
  2.2072 -        help("restore");
  2.2073 -        exit(2);
  2.2074 -    }
  2.2075 -    migrate_receive(debug, daemonize);
  2.2076 -    exit(0);
  2.2077 -}
  2.2078 -
  2.2079 -int main_save(int argc, char **argv)
  2.2080 -{
  2.2081 -    char *filename = NULL, *p = NULL;
  2.2082 -    const char *config_filename;
  2.2083 -    int checkpoint = 0;
  2.2084 -    int opt;
  2.2085 -
  2.2086 -    while ((opt = getopt(argc, argv, "hc")) != -1) {
  2.2087 -        switch (opt) {
  2.2088 -        case 'c':
  2.2089 -            checkpoint = 1;
  2.2090 -            break;
  2.2091 -        case 'h':
  2.2092 -            help("save");
  2.2093 -            exit(0);
  2.2094 -        default:
  2.2095 -            fprintf(stderr, "option not supported\n");
  2.2096 -            break;
  2.2097 -        }
  2.2098 -    }
  2.2099 -
  2.2100 -    if (argc-optind < 1 || argc-optind > 3) {
  2.2101 -        help("save");
  2.2102 -        exit(2);
  2.2103 -    }
  2.2104 -
  2.2105 -    p = argv[optind];
  2.2106 -    filename = argv[optind + 1];
  2.2107 -    config_filename = argv[optind + 2];
  2.2108 -    save_domain(p, filename, checkpoint, config_filename);
  2.2109 -    exit(0);
  2.2110 -}
  2.2111 -
  2.2112 -int main_migrate(int argc, char **argv)
  2.2113 -{
  2.2114 -    char *p = NULL;
  2.2115 -    const char *config_filename = NULL;
  2.2116 -    const char *ssh_command = "ssh";
  2.2117 -    char *rune = NULL;
  2.2118 -    char *host;
  2.2119 -    int opt, daemonize = 1, debug = 0;
  2.2120 -
  2.2121 -    while ((opt = getopt(argc, argv, "hC:s:ed")) != -1) {
  2.2122 -        switch (opt) {
  2.2123 -        case 'h':
  2.2124 -            help("migrate");
  2.2125 -            exit(0);
  2.2126 -        case 'C':
  2.2127 -            config_filename = optarg;
  2.2128 -            break;
  2.2129 -        case 's':
  2.2130 -            ssh_command = optarg;
  2.2131 -            break;
  2.2132 -        case 'e':
  2.2133 -            daemonize = 0;
  2.2134 -            break;
  2.2135 -        case 'd':
  2.2136 -            debug = 1;
  2.2137 -            break;
  2.2138 -        default:
  2.2139 -            fprintf(stderr, "option not supported\n");
  2.2140 -            break;
  2.2141 -        }
  2.2142 -    }
  2.2143 -
  2.2144 -    if (argc-optind < 2 || argc-optind > 2) {
  2.2145 -        help("save");
  2.2146 -        exit(2);
  2.2147 -    }
  2.2148 -
  2.2149 -    p = argv[optind];
  2.2150 -    host = argv[optind + 1];
  2.2151 -
  2.2152 -    if (!ssh_command[0]) {
  2.2153 -        rune= host;
  2.2154 -    } else {
  2.2155 -        asprintf(&rune, "exec %s %s xl migrate-receive%s%s",
  2.2156 -                 ssh_command, host,
  2.2157 -                 daemonize ? "" : " -e",
  2.2158 -                 debug ? " -d" : "");
  2.2159 -    }
  2.2160 -
  2.2161 -    migrate_domain(p, rune, config_filename);
  2.2162 -    exit(0);
  2.2163 -}
  2.2164 -
  2.2165 -int main_pause(int argc, char **argv)
  2.2166 -{
  2.2167 -    int opt;
  2.2168 -    char *p;
  2.2169 -    
  2.2170 -
  2.2171 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2172 -        switch (opt) {
  2.2173 -        case 'h':
  2.2174 -            help("pause");
  2.2175 -            exit(0);
  2.2176 -        default:
  2.2177 -            fprintf(stderr, "option not supported\n");
  2.2178 -            break;
  2.2179 -        }
  2.2180 -    }
  2.2181 -    if (optind >= argc) {
  2.2182 -        help("pause");
  2.2183 -        exit(2);
  2.2184 -    }
  2.2185 -
  2.2186 -    p = argv[optind];
  2.2187 -
  2.2188 -    pause_domain(p);
  2.2189 -    exit(0);
  2.2190 -}
  2.2191 -
  2.2192 -int main_unpause(int argc, char **argv)
  2.2193 -{
  2.2194 -    int opt;
  2.2195 -    char *p;
  2.2196 -    
  2.2197 -
  2.2198 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2199 -        switch (opt) {
  2.2200 -        case 'h':
  2.2201 -            help("unpause");
  2.2202 -            exit(0);
  2.2203 -        default:
  2.2204 -            fprintf(stderr, "option not supported\n");
  2.2205 -            break;
  2.2206 -        }
  2.2207 -    }
  2.2208 -    if (optind >= argc) {
  2.2209 -        help("unpause");
  2.2210 -        exit(2);
  2.2211 -    }
  2.2212 -
  2.2213 -    p = argv[optind];
  2.2214 -
  2.2215 -    unpause_domain(p);
  2.2216 -    exit(0);
  2.2217 -}
  2.2218 -
  2.2219 -int main_destroy(int argc, char **argv)
  2.2220 -{
  2.2221 -    int opt;
  2.2222 -    char *p;
  2.2223 -
  2.2224 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2225 -        switch (opt) {
  2.2226 -        case 'h':
  2.2227 -            help("destroy");
  2.2228 -            exit(0);
  2.2229 -        default:
  2.2230 -            fprintf(stderr, "option not supported\n");
  2.2231 -            break;
  2.2232 -        }
  2.2233 -    }
  2.2234 -    if (optind >= argc) {
  2.2235 -        help("destroy");
  2.2236 -        exit(2);
  2.2237 -    }
  2.2238 -
  2.2239 -    p = argv[optind];
  2.2240 -
  2.2241 -    destroy_domain(p);
  2.2242 -    exit(0);
  2.2243 -}
  2.2244 -
  2.2245 -int main_list(int argc, char **argv)
  2.2246 -{
  2.2247 -    int opt, verbose = 0;
  2.2248 -
  2.2249 -    while ((opt = getopt(argc, argv, "hv")) != -1) {
  2.2250 -        switch (opt) {
  2.2251 -        case 'h':
  2.2252 -            help("list");
  2.2253 -            exit(0);
  2.2254 -        case 'v':
  2.2255 -            verbose = 1;
  2.2256 -            break;
  2.2257 -        default:
  2.2258 -            fprintf(stderr, "option not supported\n");
  2.2259 -            break;
  2.2260 -        }
  2.2261 -    }
  2.2262 -
  2.2263 -    list_domains(verbose);
  2.2264 -    exit(0);
  2.2265 -}
  2.2266 -
  2.2267 -int main_list_vm(int argc, char **argv)
  2.2268 -{
  2.2269 -    int opt;
  2.2270 -
  2.2271 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2272 -        switch (opt) {
  2.2273 -        case 'h':
  2.2274 -            help("list-vm");
  2.2275 -            exit(0);
  2.2276 -        default:
  2.2277 -            fprintf(stderr, "option not supported\n");
  2.2278 -            break;
  2.2279 -        }
  2.2280 -    }
  2.2281 -
  2.2282 -    list_vm();
  2.2283 -    exit(0);
  2.2284 -}
  2.2285 -
  2.2286 -int main_create(int argc, char **argv)
  2.2287 -{
  2.2288 -    char *filename = NULL;
  2.2289 -    int paused = 0, debug = 0, daemonize = 1;
  2.2290 -    int opt, rc;
  2.2291 -
  2.2292 -    while ((opt = getopt(argc, argv, "hdep")) != -1) {
  2.2293 -        switch (opt) {
  2.2294 -        case 'p':
  2.2295 -            paused = 1;
  2.2296 -            break;
  2.2297 -        case 'd':
  2.2298 -            debug = 1;
  2.2299 -            break;
  2.2300 -        case 'e':
  2.2301 -            daemonize = 0;
  2.2302 -            break;
  2.2303 -        case 'h':
  2.2304 -            help("create");
  2.2305 -            exit(0);
  2.2306 -        default:
  2.2307 -            fprintf(stderr, "option not supported\n");
  2.2308 -            break;
  2.2309 -        }
  2.2310 -    }
  2.2311 -
  2.2312 -    if (optind >= argc) {
  2.2313 -        help("create");
  2.2314 -        exit(2);
  2.2315 -    }
  2.2316 -
  2.2317 -    filename = argv[optind];
  2.2318 -    rc = create_domain(debug, daemonize, filename, NULL, paused,
  2.2319 -                       -1, 0);
  2.2320 -    exit(-rc);
  2.2321 -}
  2.2322 -
  2.2323 -void button_press(char *p, char *b)
  2.2324 -{
  2.2325 -    libxl_button button;
  2.2326 -
  2.2327 -    find_domain(p);
  2.2328 -
  2.2329 -    if (!strcmp(b, "power")) {
  2.2330 -        button = POWER_BUTTON;
  2.2331 -    } else if (!strcmp(b, "sleep")) {
  2.2332 -        button = SLEEP_BUTTON;
  2.2333 -    } else {
  2.2334 -        fprintf(stderr, "%s is an invalid button identifier\n", b);
  2.2335 -        exit(2);
  2.2336 -    }
  2.2337 -
  2.2338 -    libxl_button_press(&ctx, domid, button);
  2.2339 -}
  2.2340 -
  2.2341 -int main_button_press(int argc, char **argv)
  2.2342 -{
  2.2343 -    int opt;
  2.2344 -    char *p;
  2.2345 -    char *b;
  2.2346 -
  2.2347 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2348 -        switch (opt) {
  2.2349 -        case 'h':
  2.2350 -            help("button-press");
  2.2351 -            exit(0);
  2.2352 -        default:
  2.2353 -            fprintf(stderr, "option not supported\n");
  2.2354 -            break;
  2.2355 -        }
  2.2356 -    }
  2.2357 -    if (optind >= argc - 1) {
  2.2358 -        help("button-press");
  2.2359 -        exit(2);
  2.2360 -    }
  2.2361 -
  2.2362 -    p = argv[optind];
  2.2363 -    b = argv[optind + 1];
  2.2364 -
  2.2365 -    button_press(p, b);
  2.2366 -    exit(0);
  2.2367 -}
  2.2368 -
  2.2369 -static void print_vcpuinfo(uint32_t tdomid,
  2.2370 -                           const struct libxl_vcpuinfo *vcpuinfo,
  2.2371 -                           uint32_t nr_cpus)
  2.2372 -{
  2.2373 -    int i, l;
  2.2374 -    uint64_t *cpumap;
  2.2375 -    uint64_t pcpumap;
  2.2376 -
  2.2377 -    /*      NAME  ID  VCPU */
  2.2378 -    printf("%-32s %5u %5u",
  2.2379 -           libxl_domid_to_name(&ctx, tdomid), tdomid, vcpuinfo->vcpuid);
  2.2380 -    if (!vcpuinfo->online) {
  2.2381 -        /*      CPU STA */
  2.2382 -        printf("%5c %3c%cp ", '-', '-', '-');
  2.2383 -    } else {
  2.2384 -        /*      CPU STA */
  2.2385 -        printf("%5u %3c%c- ", vcpuinfo->cpu,
  2.2386 -               vcpuinfo->running ? 'r' : '-',
  2.2387 -               vcpuinfo->blocked ? 'b' : '-');
  2.2388 -    }
  2.2389 -    /*      TIM */
  2.2390 -    printf("%9.1f  ", ((float)vcpuinfo->vcpu_time / 1e9));
  2.2391 -    /* CPU AFFINITY */
  2.2392 -    pcpumap = nr_cpus > 64 ? -1 : ((1 << nr_cpus) - 1);
  2.2393 -    for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
  2.2394 -        if (*cpumap < pcpumap) {
  2.2395 -            break;
  2.2396 -        }
  2.2397 -        if (nr_cpus > 64) {
  2.2398 -            pcpumap = -1;
  2.2399 -            nr_cpus -= 64;
  2.2400 -        } else {
  2.2401 -            pcpumap = ((1 << nr_cpus) - 1);
  2.2402 -            nr_cpus = 0;
  2.2403 -        }
  2.2404 -    }
  2.2405 -    if (!nr_cpus) {
  2.2406 -        printf("any cpu\n");
  2.2407 -    } else {
  2.2408 -        for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
  2.2409 -            pcpumap = *cpumap;
  2.2410 -            for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1)
  2.2411 -                ;
  2.2412 -            printf("%u", i);
  2.2413 -            for (l = i, pcpumap = (pcpumap >> 1); (pcpumap & 1); ++i, pcpumap >>= 1)
  2.2414 -                ;
  2.2415 -            if (l < i) {
  2.2416 -                printf("-%u", i);
  2.2417 -            }
  2.2418 -            for (++i; pcpumap; ++i, pcpumap >>= 1) {
  2.2419 -                if (pcpumap & 1) {
  2.2420 -                    printf(",%u", i);
  2.2421 -                    for (l = i, pcpumap = (pcpumap >> 1); (pcpumap & 1); ++i, pcpumap >>= 1)
  2.2422 -                        ;
  2.2423 -                    if (l < i) {
  2.2424 -                        printf("-%u", i);
  2.2425 -                    }
  2.2426 -                    ++i;
  2.2427 -                }
  2.2428 -            }
  2.2429 -            printf("\n");
  2.2430 -            nr_cpus = nr_cpus > 64 ? nr_cpus - 64 : 0;
  2.2431 -        }
  2.2432 -    }
  2.2433 -}
  2.2434 -
  2.2435 -void vcpulist(int argc, char **argv)
  2.2436 -{
  2.2437 -    struct libxl_dominfo *dominfo;
  2.2438 -    struct libxl_vcpuinfo *vcpuinfo;
  2.2439 -    struct libxl_physinfo physinfo;
  2.2440 -    int nb_vcpu, nb_domain, cpusize;
  2.2441 -
  2.2442 -    if (libxl_get_physinfo(&ctx, &physinfo) != 0) {
  2.2443 -        fprintf(stderr, "libxl_physinfo failed.\n");
  2.2444 -        goto vcpulist_out;
  2.2445 -    }
  2.2446 -    printf("%-32s %5s %5s %5s %5s %9s %s\n",
  2.2447 -           "Name", "ID", "VCPU", "CPU", "State", "Time(s)", "CPU Affinity");
  2.2448 -    if (!argc) {
  2.2449 -        if (!(dominfo = libxl_list_domain(&ctx, &nb_domain))) {
  2.2450 -            fprintf(stderr, "libxl_list_domain failed.\n");
  2.2451 -            goto vcpulist_out;
  2.2452 -        }
  2.2453 -        for (; nb_domain > 0; --nb_domain, ++dominfo) {
  2.2454 -            if (!(vcpuinfo = libxl_list_vcpu(&ctx, dominfo->domid, &nb_vcpu, &cpusize))) {
  2.2455 -                fprintf(stderr, "libxl_list_vcpu failed.\n");
  2.2456 -                goto vcpulist_out;
  2.2457 -            }
  2.2458 -            for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  2.2459 -                print_vcpuinfo(dominfo->domid, vcpuinfo, physinfo.nr_cpus);
  2.2460 -            }
  2.2461 -        }
  2.2462 -    } else {
  2.2463 -        for (; argc > 0; ++argv, --argc) {
  2.2464 -            if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) {
  2.2465 -                fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
  2.2466 -            }
  2.2467 -            if (!(vcpuinfo = libxl_list_vcpu(&ctx, domid, &nb_vcpu, &cpusize))) {
  2.2468 -                fprintf(stderr, "libxl_list_vcpu failed.\n");
  2.2469 -                goto vcpulist_out;
  2.2470 -            }
  2.2471 -            for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  2.2472 -                print_vcpuinfo(domid, vcpuinfo, physinfo.nr_cpus);
  2.2473 -            }
  2.2474 -        }
  2.2475 -    }
  2.2476 -  vcpulist_out:
  2.2477 -    ;
  2.2478 -}
  2.2479 -
  2.2480 -void main_vcpulist(int argc, char **argv)
  2.2481 -{
  2.2482 -    int opt;
  2.2483 -
  2.2484 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2485 -        switch (opt) {
  2.2486 -        case 'h':
  2.2487 -            help("vcpu-list");
  2.2488 -            exit(0);
  2.2489 -        default:
  2.2490 -            fprintf(stderr, "option `%c' not supported.\n", opt);
  2.2491 -            break;
  2.2492 -        }
  2.2493 -    }
  2.2494 -
  2.2495 -    vcpulist(argc - 1, argv + 1);
  2.2496 -    exit(0);
  2.2497 -}
  2.2498 -
  2.2499 -void vcpupin(char *d, const char *vcpu, char *cpu)
  2.2500 -{
  2.2501 -    struct libxl_vcpuinfo *vcpuinfo;
  2.2502 -    struct libxl_physinfo physinfo;
  2.2503 -    uint64_t *cpumap = NULL;
  2.2504 -
  2.2505 -    uint32_t vcpuid, cpuida, cpuidb;
  2.2506 -    char *endptr, *toka, *tokb;
  2.2507 -    int i, nb_vcpu, cpusize;
  2.2508 -
  2.2509 -    vcpuid = strtoul(vcpu, &endptr, 10);
  2.2510 -    if (vcpu == endptr) {
  2.2511 -        if (strcmp(vcpu, "all")) {
  2.2512 -            fprintf(stderr, "Error: Invalid argument.\n");
  2.2513 -            return;
  2.2514 -        }
  2.2515 -        vcpuid = -1;
  2.2516 -    }
  2.2517 -
  2.2518 -    find_domain(d);
  2.2519 -
  2.2520 -    if (libxl_get_physinfo(&ctx, &physinfo) != 0) {
  2.2521 -        fprintf(stderr, "libxl_get_physinfo failed.\n");
  2.2522 -        goto vcpupin_out1;
  2.2523 -    }
  2.2524 -
  2.2525 -    cpumap = calloc(physinfo.max_cpu_id + 1, sizeof (uint64_t));
  2.2526 -    if (!cpumap) {
  2.2527 -        goto vcpupin_out1;
  2.2528 -    }
  2.2529 -    if (strcmp(cpu, "all")) {
  2.2530 -        for (toka = strtok(cpu, ","), i = 0; toka; toka = strtok(NULL, ","), ++i) {
  2.2531 -            cpuida = strtoul(toka, &endptr, 10);
  2.2532 -            if (toka == endptr) {
  2.2533 -                fprintf(stderr, "Error: Invalid argument.\n");
  2.2534 -                goto vcpupin_out;
  2.2535 -            }
  2.2536 -            if (*endptr == '-') {
  2.2537 -                tokb = endptr + 1;
  2.2538 -                cpuidb = strtoul(tokb, &endptr, 10);
  2.2539 -                if ((tokb == endptr) || (cpuida > cpuidb)) {
  2.2540 -                    fprintf(stderr, "Error: Invalid argument.\n");
  2.2541 -                    goto vcpupin_out;
  2.2542 -                }
  2.2543 -                while (cpuida <= cpuidb) {
  2.2544 -                    cpumap[cpuida / 64] |= (1 << (cpuida % 64));
  2.2545 -                    ++cpuida;
  2.2546 -                }
  2.2547 -            } else {
  2.2548 -                cpumap[cpuida / 64] |= (1 << (cpuida % 64));
  2.2549 -            }
  2.2550 -        }
  2.2551 -    }
  2.2552 -    else {
  2.2553 -        memset(cpumap, -1, sizeof (uint64_t) * (physinfo.max_cpu_id + 1));
  2.2554 -    }
  2.2555 -
  2.2556 -    if (vcpuid != -1) {
  2.2557 -        if (libxl_set_vcpuaffinity(&ctx, domid, vcpuid,
  2.2558 -                                   cpumap, physinfo.max_cpu_id + 1) == -1) {
  2.2559 -            fprintf(stderr, "Could not set affinity for vcpu `%u'.\n", vcpuid);
  2.2560 -        }
  2.2561 -    }
  2.2562 -    else {
  2.2563 -        if (!(vcpuinfo = libxl_list_vcpu(&ctx, domid, &nb_vcpu, &cpusize))) {
  2.2564 -            fprintf(stderr, "libxl_list_vcpu failed.\n");
  2.2565 -            goto vcpupin_out;
  2.2566 -        }
  2.2567 -        for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  2.2568 -            if (libxl_set_vcpuaffinity(&ctx, domid, vcpuinfo->vcpuid,
  2.2569 -                                       cpumap, physinfo.max_cpu_id + 1) == -1) {
  2.2570 -                fprintf(stderr, "libxl_list_vcpu failed on vcpu `%u'.\n", vcpuinfo->vcpuid);
  2.2571 -            }
  2.2572 -        }
  2.2573 -    }
  2.2574 -  vcpupin_out1:
  2.2575 -    free(cpumap);
  2.2576 -  vcpupin_out:
  2.2577 -    ;
  2.2578 -}
  2.2579 -
  2.2580 -int main_vcpupin(int argc, char **argv)
  2.2581 -{
  2.2582 -    int opt;
  2.2583 -
  2.2584 -    if (argc != 4) {
  2.2585 -        help("vcpu-pin");
  2.2586 -        exit(0);
  2.2587 -    }
  2.2588 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2589 -        switch (opt) {
  2.2590 -        case 'h':
  2.2591 -            help("vcpu-pin");
  2.2592 -            exit(0);
  2.2593 -        default:
  2.2594 -            fprintf(stderr, "option `%c' not supported.\n", opt);
  2.2595 -            break;
  2.2596 -        }
  2.2597 -    }
  2.2598 -
  2.2599 -    vcpupin(argv[1], argv[2] , argv[3]);
  2.2600 -    exit(0);
  2.2601 -}
  2.2602 -
  2.2603 -void vcpuset(char *d, char* nr_vcpus)
  2.2604 -{
  2.2605 -    char *endptr;
  2.2606 -    unsigned int max_vcpus;
  2.2607 -
  2.2608 -    max_vcpus = strtoul(nr_vcpus, &endptr, 10);
  2.2609 -    if (nr_vcpus == endptr) {
  2.2610 -        fprintf(stderr, "Error: Invalid argument.\n");
  2.2611 -        return;
  2.2612 -    }
  2.2613 -
  2.2614 -    find_domain(d);
  2.2615 -
  2.2616 -    if (libxl_set_vcpucount(&ctx, domid, max_vcpus) == ERROR_INVAL) {
  2.2617 -        fprintf(stderr, "Error: Cannot set vcpus greater than max vcpus on running domain or lesser than 1.\n");
  2.2618 -    }
  2.2619 -}
  2.2620 -
  2.2621 -int main_vcpuset(int argc, char **argv)
  2.2622 -{
  2.2623 -    int opt;
  2.2624 -
  2.2625 -    if (argc != 3) {
  2.2626 -        help("vcpu-set");
  2.2627 -        exit(0);
  2.2628 -    }
  2.2629 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2630 -        switch (opt) {
  2.2631 -        case 'h':
  2.2632 -        help("vcpu-set");
  2.2633 -            exit(0);
  2.2634 -        default:
  2.2635 -            fprintf(stderr, "option `%c' not supported.\n", opt);
  2.2636 -            break;
  2.2637 -        }
  2.2638 -    }
  2.2639 -
  2.2640 -    vcpuset(argv[1], argv[2]);
  2.2641 -    exit(0);
  2.2642 -}
  2.2643 -
  2.2644 -static void output_xeninfo(void)
  2.2645 -{
  2.2646 -    const libxl_version_info *info;
  2.2647 -    int sched_id;
  2.2648 -
  2.2649 -    info = libxl_get_version_info(&ctx);
  2.2650 -    if ((sched_id = libxl_get_sched_id(&ctx)) < 0) {
  2.2651 -        fprintf(stderr, "get_sched_id sysctl failed.\n");
  2.2652 -        return;
  2.2653 -    }
  2.2654 -
  2.2655 -    printf("xen_major              : %d\n", info->xen_version_major);
  2.2656 -    printf("xen_minor              : %d\n", info->xen_version_minor);
  2.2657 -    printf("xen_extra              : %s\n", info->xen_version_extra);
  2.2658 -    printf("xen_caps               : %s\n", info->capabilities);
  2.2659 -    printf("xen_scheduler          : %s\n",
  2.2660 -        sched_id == XEN_SCHEDULER_SEDF ? "sedf" :
  2.2661 -        sched_id == XEN_SCHEDULER_CREDIT ? "credit" :
  2.2662 -        sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown");
  2.2663 -    printf("xen_pagesize           : %lu\n", info->pagesize);
  2.2664 -    printf("platform_params        : virt_start=0x%lx\n", info->virt_start);
  2.2665 -    printf("xen_changeset          : %s\n", info->changeset);
  2.2666 -    printf("xen_commandline        : %s\n", info->commandline);
  2.2667 -    printf("cc_compiler            : %s\n", info->compiler);
  2.2668 -    printf("cc_compile_by          : %s\n", info->compile_by);
  2.2669 -    printf("cc_compile_domain      : %s\n", info->compile_domain);
  2.2670 -    printf("cc_compile_date        : %s\n", info->compile_date);
  2.2671 -
  2.2672 -    return;
  2.2673 -}
  2.2674 -
  2.2675 -static void output_nodeinfo(void)
  2.2676 -{
  2.2677 -    struct utsname utsbuf;
  2.2678 -
  2.2679 -    uname(&utsbuf);
  2.2680 -
  2.2681 -    printf("host                   : %s\n", utsbuf.nodename);
  2.2682 -    printf("release                : %s\n", utsbuf.release);
  2.2683 -    printf("version                : %s\n", utsbuf.version);
  2.2684 -    printf("machine                : %s\n", utsbuf.machine);
  2.2685 -
  2.2686 -    return;
  2.2687 -}
  2.2688 -
  2.2689 -static void output_physinfo(void)
  2.2690 -{
  2.2691 -    struct libxl_physinfo info;
  2.2692 -    const libxl_version_info *vinfo;
  2.2693 -    unsigned int i;
  2.2694 -
  2.2695 -    if (libxl_get_physinfo(&ctx, &info) != 0) {
  2.2696 -        fprintf(stderr, "libxl_physinfo failed.\n");
  2.2697 -        return;
  2.2698 -    }
  2.2699 -
  2.2700 -    printf("nr_cpus                : %d\n", info.nr_cpus);
  2.2701 -    printf("nr_nodes               : %d\n", info.nr_nodes);
  2.2702 -    printf("cores_per_socket       : %d\n", info.cores_per_socket);
  2.2703 -    printf("threads_per_core       : %d\n", info.threads_per_core);
  2.2704 -    printf("cpu_mhz                : %d\n", info.cpu_khz / 1000);
  2.2705 -    printf("hw_caps                : ");
  2.2706 -    for (i = 0; i < 8; i++)
  2.2707 -        printf("%08x%c", info.hw_cap[i], i < 7 ? ':' : '\n');
  2.2708 -    printf("virt_caps              :");
  2.2709 -    if (info.phys_cap & XEN_SYSCTL_PHYSCAP_hvm)
  2.2710 -        printf(" hvm");
  2.2711 -    if (info.phys_cap & XEN_SYSCTL_PHYSCAP_hvm_directio)
  2.2712 -        printf(" hvm_directio");
  2.2713 -    printf("\n");
  2.2714 -    vinfo = libxl_get_version_info(&ctx);
  2.2715 -    i = (1 << 20) / vinfo->pagesize;
  2.2716 -    printf("total_memory           : %lu\n", info.total_pages / i);
  2.2717 -    printf("free_memory            : %lu\n", info.free_pages / i);
  2.2718 -
  2.2719 -    return;
  2.2720 -}
  2.2721 -
  2.2722 -void info(int verbose)
  2.2723 -{
  2.2724 -    output_nodeinfo();
  2.2725 -
  2.2726 -    output_physinfo();
  2.2727 -
  2.2728 -    output_xeninfo();
  2.2729 -
  2.2730 -    printf("xend_config_format     : 4\n");
  2.2731 -
  2.2732 -    return;
  2.2733 -}
  2.2734 -
  2.2735 -void main_info(int argc, char **argv)
  2.2736 -{
  2.2737 -    int opt, verbose;
  2.2738 -
  2.2739 -    verbose = 0;
  2.2740 -    while ((opt = getopt(argc, argv, "h")) != -1) {
  2.2741 -        switch (opt) {
  2.2742 -        case 'h':
  2.2743 -            help("vcpu-list");
  2.2744 -            exit(0);
  2.2745 -        default:
  2.2746 -            fprintf(stderr, "option `%c' not supported.\n", opt);
  2.2747 -            break;
  2.2748 -        }
  2.2749 -    }
  2.2750 -
  2.2751 -    info(verbose);
  2.2752 -    exit(0);
  2.2753 -}
  2.2754 -
  2.2755 -int sched_credit_domain_get(int domid, struct libxl_sched_credit *scinfo)
  2.2756 -{
  2.2757 -    int rc;
  2.2758 -
  2.2759 -    rc = libxl_sched_credit_domain_get(&ctx, domid, scinfo);
  2.2760 -    if (rc)
  2.2761 -        fprintf(stderr, "libxl_sched_credit_domain_get failed.\n");
  2.2762 -    
  2.2763 -    return rc;
  2.2764 -}
  2.2765 -
  2.2766 -int sched_credit_domain_set(int domid, struct libxl_sched_credit *scinfo)
  2.2767 -{
  2.2768 -    int rc;
  2.2769 -
  2.2770 -    rc = libxl_sched_credit_domain_set(&ctx, domid, scinfo);
  2.2771 -    if (rc)
  2.2772 -        fprintf(stderr, "libxl_sched_credit_domain_set failed.\n");
  2.2773 -
  2.2774 -    return rc;
  2.2775 -}
  2.2776 -
  2.2777 -void sched_credit_domain_output(int domid, struct libxl_sched_credit *scinfo)
  2.2778 -{
  2.2779 -    printf("%-33s %4d %6d %4d\n",
  2.2780 -        libxl_domid_to_name(&ctx, domid),
  2.2781 -        domid,
  2.2782 -        scinfo->weight,
  2.2783 -        scinfo->cap);
  2.2784 -}
  2.2785 -
  2.2786 -void main_sched_credit(int argc, char **argv)
  2.2787 -{
  2.2788 -    struct libxl_dominfo *info;
  2.2789 -    struct libxl_sched_credit scinfo;
  2.2790 -    int nb_domain, i;
  2.2791 -    char *dom = NULL;
  2.2792 -    int weight = 256, cap = 0, opt_w = 0, opt_c = 0;
  2.2793 -    int opt, rc;
  2.2794 -
  2.2795 -    while ((opt = getopt(argc, argv, "hd:w:c:")) != -1) {
  2.2796 -        switch (opt) {
  2.2797 -        case 'd':
  2.2798 -            dom = optarg;
  2.2799 -            break;
  2.2800 -        case 'w':
  2.2801 -            weight = strtol(optarg, NULL, 10);
  2.2802 -            opt_w = 1;
  2.2803 -            break;
  2.2804 -        case 'c':
  2.2805 -            cap = strtol(optarg, NULL, 10);
  2.2806 -            opt_c = 1;
  2.2807 -            break;
  2.2808 -        case 'h':
  2.2809 -            help("sched-credit");
  2.2810 -            exit(0);
  2.2811 -        default:
  2.2812 -            fprintf(stderr, "option `%c' not supported.\n", opt);
  2.2813 -            break;
  2.2814 -        }
  2.2815 -    }
  2.2816 -
  2.2817 -    if (!dom && (opt_w || opt_c)) {
  2.2818 -        fprintf(stderr, "Must specify a domain.\n");
  2.2819 -        exit(1);
  2.2820 -    }
  2.2821 -
  2.2822 -    if (!dom) { /* list all domain's credit scheduler info */
  2.2823 -        info = libxl_list_domain(&ctx, &nb_domain);
  2.2824 -        if (!info) {
  2.2825 -            fprintf(stderr, "libxl_domain_infolist failed.\n");
  2.2826 -            exit(1);
  2.2827 -        }
  2.2828 -
  2.2829 -        printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
  2.2830 -        for (i = 0; i < nb_domain; i++) {
  2.2831 -            rc = sched_credit_domain_get(info[i].domid, &scinfo);
  2.2832 -            if (rc)
  2.2833 -                exit(-rc);
  2.2834 -            sched_credit_domain_output(info[i].domid, &scinfo);
  2.2835 -        }
  2.2836 -    } else {
  2.2837 -        find_domain(dom);
  2.2838 -
  2.2839 -        rc = sched_credit_domain_get(domid, &scinfo);
  2.2840 -        if (rc)
  2.2841 -            exit(-rc);
  2.2842 -
  2.2843 -        if (!opt_w && !opt_c) { /* output credit scheduler info */
  2.2844 -            printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
  2.2845 -            sched_credit_domain_output(domid, &scinfo);
  2.2846 -        } else { /* set credit scheduler paramaters */
  2.2847 -            if (opt_w)
  2.2848 -                scinfo.weight = weight;
  2.2849 -            if (opt_c)
  2.2850 -                scinfo.cap = cap;
  2.2851 -            rc = sched_credit_domain_set(domid, &scinfo);
  2.2852 -            if (rc)
  2.2853 -                exit(-rc);
  2.2854 -        }
  2.2855 -    }
  2.2856 -
  2.2857 -    exit(0);
  2.2858 -}
  2.2859 -
  2.2860  int main(int argc, char **argv)
  2.2861  {
  2.2862      if (argc < 2) {
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/libxl/xl_cmdimpl.c	Tue May 04 11:23:17 2010 +0100
     3.3 @@ -0,0 +1,2865 @@
     3.4 +/*
     3.5 + * Copyright (C) 2009      Citrix Ltd.
     3.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     3.7 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     3.8 + *
     3.9 + * This program is free software; you can redistribute it and/or modify
    3.10 + * it under the terms of the GNU Lesser General Public License as published
    3.11 + * by the Free Software Foundation; version 2.1 only. with the special
    3.12 + * exception on linking described in file LICENSE.
    3.13 + *
    3.14 + * This program is distributed in the hope that it will be useful,
    3.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.17 + * GNU Lesser General Public License for more details.
    3.18 + */
    3.19 +
    3.20 +#include "libxl_osdeps.h"
    3.21 +
    3.22 +#include <stdio.h>
    3.23 +#include <assert.h>
    3.24 +#include <stdlib.h>
    3.25 +#include <string.h>
    3.26 +#include <unistd.h>
    3.27 +#include <sys/time.h> /* for time */
    3.28 +#include <getopt.h>
    3.29 +#include <sys/types.h>
    3.30 +#include <sys/stat.h>
    3.31 +#include <fcntl.h>
    3.32 +#include <signal.h>
    3.33 +#include <sys/socket.h>
    3.34 +#include <sys/select.h>
    3.35 +#include <arpa/inet.h>
    3.36 +#include <sys/utsname.h> /* for utsname in xl info */
    3.37 +#include <xenctrl.h>
    3.38 +#include <ctype.h>
    3.39 +#include <inttypes.h>
    3.40 +
    3.41 +#include "libxl.h"
    3.42 +#include "libxl_utils.h"
    3.43 +#include "libxlutil.h"
    3.44 +
    3.45 +#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
    3.46 +
    3.47 +int logfile = 2;
    3.48 +
    3.49 +/* every libxl action in xl uses this same libxl context */
    3.50 +struct libxl_ctx ctx;
    3.51 +
    3.52 +/* when we operate on a domain, it is this one: */
    3.53 +static uint32_t domid;
    3.54 +static const char *common_domname;
    3.55 +
    3.56 +
    3.57 +static const char savefileheader_magic[32]=
    3.58 +    "Xen saved domain, xl format\n \0 \r";
    3.59 +
    3.60 +static const char migrate_receiver_banner[]=
    3.61 +    "xl migration receiver ready, send binary domain data.\n";
    3.62 +static const char migrate_receiver_ready[]=
    3.63 +    "domain received, ready to unpause";
    3.64 +static const char migrate_permission_to_go[]=
    3.65 +    "domain is yours, you are cleared to unpause";
    3.66 +static const char migrate_report[]=
    3.67 +    "my copy unpause results are as follows";
    3.68 +  /* followed by one byte:
    3.69 +   *     0: everything went well, domain is running
    3.70 +   *            next thing is we all exit
    3.71 +   * non-0: things went badly
    3.72 +   *            next thing should be a migrate_permission_to_go
    3.73 +   *            from target to source
    3.74 +   */
    3.75 +
    3.76 +struct save_file_header {
    3.77 +    char magic[32]; /* savefileheader_magic */
    3.78 +    /* All uint32_ts are in domain's byte order. */
    3.79 +    uint32_t byteorder; /* SAVEFILE_BYTEORDER_VALUE */
    3.80 +    uint32_t mandatory_flags; /* unknown flags => reject restore */
    3.81 +    uint32_t optional_flags; /* unknown flags => reject restore */
    3.82 +    uint32_t optional_data_len; /* skip, or skip tail, if not understood */
    3.83 +};
    3.84 +
    3.85 +/* Optional data, in order:
    3.86 + *   4 bytes uint32_t  config file size
    3.87 + *   n bytes           config file in Unix text file format
    3.88 + */
    3.89 +
    3.90 +#define SAVEFILE_BYTEORDER_VALUE ((uint32_t)0x01020304UL)
    3.91 +
    3.92 +static int domain_qualifier_to_domid(const char *p, uint32_t *domid_r,
    3.93 +                                     int *was_name_r)
    3.94 +{
    3.95 +    int i, alldigit;
    3.96 +
    3.97 +    alldigit = 1;
    3.98 +    for (i = 0; p[i]; i++) {
    3.99 +        if (!isdigit((uint8_t)p[i])) {
   3.100 +            alldigit = 0;
   3.101 +            break;
   3.102 +        }
   3.103 +    }
   3.104 +
   3.105 +    if (i > 0 && alldigit) {
   3.106 +        *domid_r = strtoul(p, NULL, 10);
   3.107 +        if (was_name_r) *was_name_r = 0;
   3.108 +        return 0;
   3.109 +    } else {
   3.110 +        /* check here if it's a uuid and do proper conversion */
   3.111 +    }
   3.112 +    if (was_name_r) *was_name_r = 1;
   3.113 +    return libxl_name_to_domid(&ctx, p, domid_r);
   3.114 +}
   3.115 +
   3.116 +static void find_domain(const char *p)
   3.117 +{
   3.118 +    int rc, was_name;
   3.119 +
   3.120 +    rc = domain_qualifier_to_domid(p, &domid, &was_name);
   3.121 +    if (rc) {
   3.122 +        fprintf(stderr, "%s is an invalid domain identifier (rc=%d)\n", p, rc);
   3.123 +        exit(2);
   3.124 +    }
   3.125 +    common_domname = was_name ? p : 0;
   3.126 +}
   3.127 +
   3.128 +#define LOG(_f, _a...)   dolog(__FILE__, __LINE__, __func__, _f "\n", ##_a)
   3.129 +
   3.130 +void dolog(const char *file, int line, const char *func, char *fmt, ...)
   3.131 +{
   3.132 +    va_list ap;
   3.133 +    char *s;
   3.134 +    int rc;
   3.135 +
   3.136 +    va_start(ap, fmt);
   3.137 +    rc = vasprintf(&s, fmt, ap);
   3.138 +    va_end(ap);
   3.139 +    if (rc >= 0)
   3.140 +        write(logfile, s, rc);
   3.141 +}
   3.142 +
   3.143 +static void init_create_info(libxl_domain_create_info *c_info)
   3.144 +{
   3.145 +    memset(c_info, '\0', sizeof(*c_info));
   3.146 +    c_info->xsdata = NULL;
   3.147 +    c_info->platformdata = NULL;
   3.148 +    c_info->hvm = 1;
   3.149 +    c_info->oos = 1;
   3.150 +    c_info->ssidref = 0;
   3.151 +}
   3.152 +
   3.153 +static void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info)
   3.154 +{
   3.155 +    memset(b_info, '\0', sizeof(*b_info));
   3.156 +    b_info->timer_mode = -1;
   3.157 +    b_info->hpet = 1;
   3.158 +    b_info->vpt_align = -1;
   3.159 +    b_info->max_vcpus = 1;
   3.160 +    b_info->max_memkb = 32 * 1024;
   3.161 +    b_info->target_memkb = b_info->max_memkb;
   3.162 +    if (c_info->hvm) {
   3.163 +        b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus);
   3.164 +        b_info->video_memkb = 8 * 1024;
   3.165 +        b_info->kernel = "/usr/lib/xen/boot/hvmloader";
   3.166 +        b_info->hvm = 1;
   3.167 +        b_info->u.hvm.pae = 1;
   3.168 +        b_info->u.hvm.apic = 1;
   3.169 +        b_info->u.hvm.acpi = 1;
   3.170 +        b_info->u.hvm.nx = 1;
   3.171 +        b_info->u.hvm.viridian = 0;
   3.172 +    } else {
   3.173 +        b_info->u.pv.slack_memkb = 8 * 1024;
   3.174 +    }
   3.175 +}
   3.176 +
   3.177 +static void init_dm_info(libxl_device_model_info *dm_info,
   3.178 +        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
   3.179 +{
   3.180 +    int i;
   3.181 +    memset(dm_info, '\0', sizeof(*dm_info));
   3.182 +
   3.183 +    for (i = 0; i < 16; i++) {
   3.184 +        dm_info->uuid[i] = rand();
   3.185 +    }
   3.186 +
   3.187 +    dm_info->dom_name = c_info->name;
   3.188 +    dm_info->device_model = "/usr/lib/xen/bin/qemu-dm";
   3.189 +    dm_info->videoram = b_info->video_memkb / 1024;
   3.190 +    dm_info->apic = b_info->u.hvm.apic;
   3.191 +
   3.192 +    dm_info->stdvga = 0;
   3.193 +    dm_info->vnc = 1;
   3.194 +    dm_info->vnclisten = "127.0.0.1";
   3.195 +    dm_info->vncdisplay = 0;
   3.196 +    dm_info->vncunused = 0;
   3.197 +    dm_info->keymap = NULL;
   3.198 +    dm_info->sdl = 0;
   3.199 +    dm_info->opengl = 0;
   3.200 +    dm_info->nographic = 0;
   3.201 +    dm_info->serial = NULL;
   3.202 +    dm_info->boot = "cda";
   3.203 +    dm_info->usb = 0;
   3.204 +    dm_info->usbdevice = NULL;
   3.205 +}
   3.206 +
   3.207 +static void init_nic_info(libxl_device_nic *nic_info, int devnum)
   3.208 +{
   3.209 +    memset(nic_info, '\0', sizeof(*nic_info));
   3.210 +
   3.211 +    nic_info->backend_domid = 0;
   3.212 +    nic_info->domid = 0;
   3.213 +    nic_info->devid = devnum;
   3.214 +    nic_info->mtu = 1492;
   3.215 +    nic_info->model = "e1000";
   3.216 +    nic_info->mac[0] = 0x00;
   3.217 +    nic_info->mac[1] = 0x16;
   3.218 +    nic_info->mac[2] = 0x3e;
   3.219 +    nic_info->mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
   3.220 +    nic_info->mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
   3.221 +    nic_info->mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
   3.222 +    nic_info->ifname = NULL;
   3.223 +    nic_info->bridge = "xenbr0";
   3.224 +    nic_info->script = "/etc/xen/scripts/vif-bridge";
   3.225 +    nic_info->nictype = NICTYPE_IOEMU;
   3.226 +}
   3.227 +
   3.228 +static void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
   3.229 +{
   3.230 +    memset(vfb, 0x00, sizeof(libxl_device_vfb));
   3.231 +    vfb->devid = dev_num;
   3.232 +    vfb->vnc = 1;
   3.233 +    vfb->vnclisten = "127.0.0.1";
   3.234 +    vfb->vncdisplay = 0;
   3.235 +    vfb->vncunused = 1;
   3.236 +    vfb->keymap = NULL;
   3.237 +    vfb->sdl = 0;
   3.238 +    vfb->opengl = 0;
   3.239 +}
   3.240 +
   3.241 +static void init_vkb_info(libxl_device_vkb *vkb, int dev_num)
   3.242 +{
   3.243 +    memset(vkb, 0x00, sizeof(libxl_device_vkb));
   3.244 +    vkb->devid = dev_num;
   3.245 +}
   3.246 +
   3.247 +static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
   3.248 +{
   3.249 +    memset(console, 0x00, sizeof(libxl_device_console));
   3.250 +    console->devid = dev_num;
   3.251 +    console->constype = CONSTYPE_XENCONSOLED;
   3.252 +    if (state)
   3.253 +        console->build_state = state;
   3.254 +}
   3.255 +
   3.256 +static void printf_info(libxl_domain_create_info *c_info,
   3.257 +                        libxl_domain_build_info *b_info,
   3.258 +                        libxl_device_disk *disks,
   3.259 +                        int num_disks,
   3.260 +                        libxl_device_nic *vifs,
   3.261 +                        int num_vifs,
   3.262 +                        libxl_device_pci *pcidevs,
   3.263 +                        int num_pcidevs,
   3.264 +                        libxl_device_vfb *vfbs,
   3.265 +                        int num_vfbs,
   3.266 +                        libxl_device_vkb *vkb,
   3.267 +                        int num_vkbs,
   3.268 +                        libxl_device_model_info *dm_info)
   3.269 +{
   3.270 +    int i;
   3.271 +    printf("*** domain_create_info ***\n");
   3.272 +    printf("hvm: %d\n", c_info->hvm);
   3.273 +    printf("hap: %d\n", c_info->hap);
   3.274 +    printf("oos: %d\n", c_info->oos);
   3.275 +    printf("ssidref: %d\n", c_info->ssidref);
   3.276 +    printf("name: %s\n", c_info->name);
   3.277 +    printf("uuid: " UUID_FMT "\n",
   3.278 +           (c_info->uuid)[0], (c_info->uuid)[1], (c_info->uuid)[2], (c_info->uuid)[3],
   3.279 +           (c_info->uuid)[4], (c_info->uuid)[5], (c_info->uuid)[6], (c_info->uuid)[7],
   3.280 +           (c_info->uuid)[8], (c_info->uuid)[9], (c_info->uuid)[10], (c_info->uuid)[11],
   3.281 +           (c_info->uuid)[12], (c_info->uuid)[13], (c_info->uuid)[14], (c_info->uuid)[15]);
   3.282 +    if (c_info->xsdata)
   3.283 +        printf("xsdata: contains data\n");
   3.284 +    else
   3.285 +        printf("xsdata: (null)\n");
   3.286 +    if (c_info->platformdata)
   3.287 +        printf("platformdata: contains data\n");
   3.288 +    else
   3.289 +        printf("platformdata: (null)\n");
   3.290 +
   3.291 +
   3.292 +    printf("\n\n\n*** domain_build_info ***\n");
   3.293 +    printf("timer_mode: %d\n", b_info->timer_mode);
   3.294 +    printf("hpet: %d\n", b_info->hpet);
   3.295 +    printf("vpt_align: %d\n", b_info->vpt_align);
   3.296 +    printf("max_vcpus: %d\n", b_info->max_vcpus);
   3.297 +    printf("tsc_mode: %d\n", b_info->tsc_mode);
   3.298 +    printf("max_memkb: %d\n", b_info->max_memkb);
   3.299 +    printf("target_memkb: %d\n", b_info->target_memkb);
   3.300 +    printf("kernel: %s\n", b_info->kernel);
   3.301 +    printf("hvm: %d\n", b_info->hvm);
   3.302 +
   3.303 +    if (c_info->hvm) {
   3.304 +        printf("video_memkb: %d\n", b_info->video_memkb);
   3.305 +        printf("shadow_memkb: %d\n", b_info->shadow_memkb);
   3.306 +        printf("    pae: %d\n", b_info->u.hvm.pae);
   3.307 +        printf("    apic: %d\n", b_info->u.hvm.apic);
   3.308 +        printf("    acpi: %d\n", b_info->u.hvm.acpi);
   3.309 +        printf("    nx: %d\n", b_info->u.hvm.nx);
   3.310 +        printf("    viridian: %d\n", b_info->u.hvm.viridian);
   3.311 +    } else {
   3.312 +        printf("cmdline: %s\n", b_info->u.pv.cmdline);
   3.313 +        printf("ramdisk: %s\n", b_info->u.pv.ramdisk);
   3.314 +    }
   3.315 +
   3.316 +    for (i = 0; i < num_disks; i++) {
   3.317 +        printf("\n\n\n*** disks_info: %d ***\n", i);
   3.318 +        printf("backend_domid %d\n", disks[i].backend_domid);
   3.319 +        printf("domid %d\n", disks[i].domid);
   3.320 +        printf("physpath %s\n", disks[i].physpath);
   3.321 +        printf("phystype %d\n", disks[i].phystype);
   3.322 +        printf("virtpath %s\n", disks[i].virtpath);
   3.323 +        printf("unpluggable %d\n", disks[i].unpluggable);
   3.324 +        printf("readwrite %d\n", disks[i].readwrite);
   3.325 +        printf("is_cdrom %d\n", disks[i].is_cdrom);
   3.326 +    }
   3.327 +
   3.328 +    for (i = 0; i < num_vifs; i++) {
   3.329 +        printf("\n\n\n*** vifs_info: %d ***\n", i);
   3.330 +        printf("backend_domid %d\n", vifs[i].backend_domid);
   3.331 +        printf("domid %d\n", vifs[i].domid);
   3.332 +        printf("devid %d\n", vifs[i].devid);
   3.333 +        printf("mtu %d\n", vifs[i].mtu);
   3.334 +        printf("model %s\n", vifs[i].model);
   3.335 +        printf("mac %02x:%02x:%02x:%02x:%02x:%02x\n", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   3.336 +    }
   3.337 +
   3.338 +    for (i = 0; i < num_pcidevs; i++) {
   3.339 +        printf("\n\n\n*** pcidevs_info: %d ***\n", i);
   3.340 +        printf("pci dev "PCI_BDF_VDEVFN"\n", pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func, pcidevs[i].vdevfn);
   3.341 +        printf("opts msitranslate %d power_mgmt %d\n", pcidevs[i].msitranslate, pcidevs[i].power_mgmt);
   3.342 +    }
   3.343 +
   3.344 +    for (i = 0; i < num_vfbs; i++) {
   3.345 +        printf("\n\n\n*** vfbs_info: %d ***\n", i);
   3.346 +        printf("backend_domid %d\n", vfbs[i].backend_domid);
   3.347 +        printf("domid %d\n", vfbs[i].domid);
   3.348 +        printf("devid %d\n", vfbs[i].devid);
   3.349 +        printf("vnc: %d\n", vfbs[i].vnc);
   3.350 +        printf("vnclisten: %s\n", vfbs[i].vnclisten);
   3.351 +        printf("vncdisplay: %d\n", vfbs[i].vncdisplay);
   3.352 +        printf("vncunused: %d\n", vfbs[i].vncunused);
   3.353 +        printf("keymap: %s\n", vfbs[i].keymap);
   3.354 +        printf("sdl: %d\n", vfbs[i].sdl);
   3.355 +        printf("opengl: %d\n", vfbs[i].opengl);
   3.356 +        printf("display: %s\n", vfbs[i].display);
   3.357 +        printf("xauthority: %s\n", vfbs[i].xauthority);
   3.358 +    }
   3.359 +
   3.360 +    if (c_info->hvm) {
   3.361 +        printf("\n\n\n*** device_model_info ***\n");
   3.362 +        printf("domid: %d\n", dm_info->domid);
   3.363 +        printf("dom_name: %s\n", dm_info->dom_name);
   3.364 +        printf("device_model: %s\n", dm_info->device_model);
   3.365 +        printf("videoram: %d\n", dm_info->videoram);
   3.366 +        printf("stdvga: %d\n", dm_info->stdvga);
   3.367 +        printf("vnc: %d\n", dm_info->vnc);
   3.368 +        printf("vnclisten: %s\n", dm_info->vnclisten);
   3.369 +        printf("vncdisplay: %d\n", dm_info->vncdisplay);
   3.370 +        printf("vncunused: %d\n", dm_info->vncunused);
   3.371 +        printf("keymap: %s\n", dm_info->keymap);
   3.372 +        printf("sdl: %d\n", dm_info->sdl);
   3.373 +        printf("opengl: %d\n", dm_info->opengl);
   3.374 +        printf("nographic: %d\n", dm_info->nographic);
   3.375 +        printf("serial: %s\n", dm_info->serial);
   3.376 +        printf("boot: %s\n", dm_info->boot);
   3.377 +        printf("usb: %d\n", dm_info->usb);
   3.378 +        printf("usbdevice: %s\n", dm_info->usbdevice);
   3.379 +        printf("apic: %d\n", dm_info->apic);
   3.380 +    }
   3.381 +}
   3.382 +
   3.383 +static void parse_config_data(const char *configfile_filename_report,
   3.384 +                              const char *configfile_data,
   3.385 +                              int configfile_len,
   3.386 +                              libxl_domain_create_info *c_info,
   3.387 +                              libxl_domain_build_info *b_info,
   3.388 +                              libxl_device_disk **disks,
   3.389 +                              int *num_disks,
   3.390 +                              libxl_device_nic **vifs,
   3.391 +                              int *num_vifs,
   3.392 +                              libxl_device_pci **pcidevs,
   3.393 +                              int *num_pcidevs,
   3.394 +                              libxl_device_vfb **vfbs,
   3.395 +                              int *num_vfbs,
   3.396 +                              libxl_device_vkb **vkbs,
   3.397 +                              int *num_vkbs,
   3.398 +                              libxl_device_model_info *dm_info)
   3.399 +{
   3.400 +    const char *buf;
   3.401 +    long l;
   3.402 +    XLU_Config *config;
   3.403 +    XLU_ConfigList *vbds, *nics, *pcis, *cvfbs;
   3.404 +    int pci_power_mgmt = 0;
   3.405 +    int pci_msitranslate = 1;
   3.406 +    int i, e;
   3.407 +
   3.408 +    config= xlu_cfg_init(stderr, configfile_filename_report);
   3.409 +    if (!config) {
   3.410 +        fprintf(stderr, "Failed to allocate for configuration\n");
   3.411 +        exit(1);
   3.412 +    }
   3.413 +
   3.414 +    e= xlu_cfg_readdata(config, configfile_data, configfile_len);
   3.415 +    if (e) {
   3.416 +        fprintf(stderr, "Failed to parse config file: %s\n", strerror(e));
   3.417 +        exit(1);
   3.418 +    }
   3.419 +
   3.420 +    init_create_info(c_info);
   3.421 +
   3.422 +    c_info->hvm = 0;
   3.423 +    if (!xlu_cfg_get_string (config, "builder", &buf) &&
   3.424 +        !strncmp(buf, "hvm", strlen(buf)))
   3.425 +        c_info->hvm = 1;
   3.426 +
   3.427 +    /* hap is missing */
   3.428 +    if (!xlu_cfg_get_string (config, "name", &buf))
   3.429 +        c_info->name = strdup(buf);
   3.430 +    else
   3.431 +        c_info->name = "test";
   3.432 +    for (i = 0; i < 16; i++) {
   3.433 +        c_info->uuid[i] = rand();
   3.434 +    }
   3.435 +
   3.436 +    if (!xlu_cfg_get_long(config, "oos", &l))
   3.437 +        c_info->oos = l;
   3.438 +
   3.439 +    init_build_info(b_info, c_info);
   3.440 +
   3.441 +    /* the following is the actual config parsing with overriding values in the structures */
   3.442 +    if (!xlu_cfg_get_long (config, "vcpus", &l))
   3.443 +        b_info->max_vcpus = l;
   3.444 +
   3.445 +    if (!xlu_cfg_get_long (config, "memory", &l)) {
   3.446 +        b_info->max_memkb = l * 1024;
   3.447 +        b_info->target_memkb = b_info->max_memkb;
   3.448 +    }
   3.449 +
   3.450 +    if (!xlu_cfg_get_long(config, "tsc_mode", &l))
   3.451 +        b_info->tsc_mode = l;
   3.452 +
   3.453 +    if (!xlu_cfg_get_long (config, "shadow_memory", &l))
   3.454 +        b_info->shadow_memkb = l * 1024;
   3.455 +
   3.456 +    if (!xlu_cfg_get_long (config, "videoram", &l))
   3.457 +        b_info->video_memkb = l * 1024;
   3.458 +
   3.459 +    if (!xlu_cfg_get_string (config, "kernel", &buf))
   3.460 +        b_info->kernel = strdup(buf);
   3.461 +
   3.462 +    if (c_info->hvm == 1) {
   3.463 +        if (!xlu_cfg_get_long (config, "pae", &l))
   3.464 +            b_info->u.hvm.pae = l;
   3.465 +        if (!xlu_cfg_get_long (config, "apic", &l))
   3.466 +            b_info->u.hvm.apic = l;
   3.467 +        if (!xlu_cfg_get_long (config, "acpi", &l))
   3.468 +            b_info->u.hvm.acpi = l;
   3.469 +        if (!xlu_cfg_get_long (config, "nx", &l))
   3.470 +            b_info->u.hvm.nx = l;
   3.471 +        if (!xlu_cfg_get_long (config, "viridian", &l))
   3.472 +            b_info->u.hvm.viridian = l;
   3.473 +    } else {
   3.474 +        char *cmdline;
   3.475 +        if (!xlu_cfg_get_string (config, "root", &buf)) {
   3.476 +            asprintf(&cmdline, "root=%s", buf);
   3.477 +            b_info->u.pv.cmdline = cmdline;
   3.478 +        }
   3.479 +        if (!xlu_cfg_get_string (config, "ramdisk", &buf))
   3.480 +            b_info->u.pv.ramdisk = strdup(buf);
   3.481 +    }
   3.482 +
   3.483 +    if (!xlu_cfg_get_list (config, "disk", &vbds, 0)) {
   3.484 +        *num_disks = 0;
   3.485 +        *disks = NULL;
   3.486 +        while ((buf = xlu_cfg_get_listitem (vbds, *num_disks)) != NULL) {
   3.487 +            char *buf2 = strdup(buf);
   3.488 +            char *p, *p2;
   3.489 +            *disks = (libxl_device_disk *) realloc(*disks, sizeof (libxl_device_disk) * ((*num_disks) + 1));
   3.490 +            (*disks)[*num_disks].backend_domid = 0;
   3.491 +            (*disks)[*num_disks].domid = 0;
   3.492 +            (*disks)[*num_disks].unpluggable = 0;
   3.493 +            p = strtok(buf2, ",:");
   3.494 +            while (*p == ' ')
   3.495 +                p++;
   3.496 +            if (!strcmp(p, "phy")) {
   3.497 +                (*disks)[*num_disks].phystype = PHYSTYPE_PHY;
   3.498 +            } else if (!strcmp(p, "file")) {
   3.499 +                (*disks)[*num_disks].phystype = PHYSTYPE_FILE;
   3.500 +            } else if (!strcmp(p, "tap")) {
   3.501 +                p = strtok(NULL, ":");
   3.502 +                if (!strcmp(p, "aio")) {
   3.503 +                    (*disks)[*num_disks].phystype = PHYSTYPE_AIO;
   3.504 +                } else if (!strcmp(p, "vhd")) {
   3.505 +                    (*disks)[*num_disks].phystype = PHYSTYPE_VHD;
   3.506 +                } else if (!strcmp(p, "qcow")) {
   3.507 +                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW;
   3.508 +                } else if (!strcmp(p, "qcow2")) {
   3.509 +                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW2;
   3.510 +                }
   3.511 +            }
   3.512 +            p = strtok(NULL, ",");
   3.513 +            while (*p == ' ')
   3.514 +                p++;
   3.515 +            (*disks)[*num_disks].physpath= strdup(p);
   3.516 +            p = strtok(NULL, ",");
   3.517 +            while (*p == ' ')
   3.518 +                p++;
   3.519 +            p2 = strchr(p, ':');
   3.520 +            if (p2 == NULL) {
   3.521 +                (*disks)[*num_disks].virtpath = strdup(p);
   3.522 +                (*disks)[*num_disks].is_cdrom = 0;
   3.523 +                (*disks)[*num_disks].unpluggable = 1;
   3.524 +            } else {
   3.525 +                *p2 = '\0';
   3.526 +                (*disks)[*num_disks].virtpath = strdup(p);
   3.527 +                if (!strcmp(p2 + 1, "cdrom")) {
   3.528 +                    (*disks)[*num_disks].is_cdrom = 1;
   3.529 +                    (*disks)[*num_disks].unpluggable = 1;
   3.530 +                } else
   3.531 +                    (*disks)[*num_disks].is_cdrom = 0;
   3.532 +            }
   3.533 +            p = strtok(NULL, ",");
   3.534 +            while (*p == ' ')
   3.535 +                p++;
   3.536 +            (*disks)[*num_disks].readwrite = (p[0] == 'w') ? 1 : 0;
   3.537 +            free(buf2);
   3.538 +            *num_disks = (*num_disks) + 1;
   3.539 +        }
   3.540 +    }
   3.541 +
   3.542 +    if (!xlu_cfg_get_list (config, "vif", &nics, 0)) {
   3.543 +        *num_vifs = 0;
   3.544 +        *vifs = NULL;
   3.545 +        while ((buf = xlu_cfg_get_listitem (nics, *num_vifs)) != NULL) {
   3.546 +            char *buf2 = strdup(buf);
   3.547 +            char *p, *p2;
   3.548 +            *vifs = (libxl_device_nic *) realloc(*vifs, sizeof (libxl_device_nic) * ((*num_vifs) + 1));
   3.549 +            init_nic_info((*vifs) + (*num_vifs), (*num_vifs) + 1);
   3.550 +            p = strtok(buf2, ",");
   3.551 +            if (!p)
   3.552 +                goto skip;
   3.553 +            do {
   3.554 +                while (*p == ' ')
   3.555 +                    p++;
   3.556 +                if ((p2 = strchr(p, '=')) == NULL)
   3.557 +                    break;
   3.558 +                *p2 = '\0';
   3.559 +                if (!strcmp(p, "model")) {
   3.560 +                    (*vifs)[*num_vifs].model = strdup(p2 + 1);
   3.561 +                } else if (!strcmp(p, "mac")) {
   3.562 +                    char *p3 = p2 + 1;
   3.563 +                    *(p3 + 2) = '\0';
   3.564 +                    (*vifs)[*num_vifs].mac[0] = strtol(p3, NULL, 16);
   3.565 +                    p3 = p3 + 3;
   3.566 +                    *(p3 + 2) = '\0';
   3.567 +                    (*vifs)[*num_vifs].mac[1] = strtol(p3, NULL, 16);
   3.568 +                    p3 = p3 + 3;
   3.569 +                    *(p3 + 2) = '\0';
   3.570 +                    (*vifs)[*num_vifs].mac[2] = strtol(p3, NULL, 16);
   3.571 +                    p3 = p3 + 3;
   3.572 +                    *(p3 + 2) = '\0';
   3.573 +                    (*vifs)[*num_vifs].mac[3] = strtol(p3, NULL, 16);
   3.574 +                    p3 = p3 + 3;
   3.575 +                    *(p3 + 2) = '\0';
   3.576 +                    (*vifs)[*num_vifs].mac[4] = strtol(p3, NULL, 16);
   3.577 +                    p3 = p3 + 3;
   3.578 +                    *(p3 + 2) = '\0';
   3.579 +                    (*vifs)[*num_vifs].mac[5] = strtol(p3, NULL, 16);
   3.580 +                } else if (!strcmp(p, "bridge")) {
   3.581 +                    (*vifs)[*num_vifs].bridge = strdup(p2 + 1);
   3.582 +                } else if (!strcmp(p, "type")) {
   3.583 +                    if (!strcmp(p2 + 1, "ioemu"))
   3.584 +                        (*vifs)[*num_vifs].nictype = NICTYPE_IOEMU;
   3.585 +                    else
   3.586 +                        (*vifs)[*num_vifs].nictype = NICTYPE_VIF;
   3.587 +                } else if (!strcmp(p, "ip")) {
   3.588 +                    inet_pton(AF_INET, p2 + 1, &((*vifs)[*num_vifs].ip));
   3.589 +                } else if (!strcmp(p, "script")) {
   3.590 +                    (*vifs)[*num_vifs].script = strdup(p2 + 1);
   3.591 +                } else if (!strcmp(p, "vifname")) {
   3.592 +                    (*vifs)[*num_vifs].ifname = strdup(p2 + 1);
   3.593 +                } else if (!strcmp(p, "rate")) {
   3.594 +                    fprintf(stderr, "the rate parameter for vifs is currently not supported\n");
   3.595 +                } else if (!strcmp(p, "accel")) {
   3.596 +                    fprintf(stderr, "the accel parameter for vifs is currently not supported\n");
   3.597 +                }
   3.598 +            } while ((p = strtok(NULL, ",")) != NULL);
   3.599 +skip:
   3.600 +            free(buf2);
   3.601 +            *num_vifs = (*num_vifs) + 1;
   3.602 +        }
   3.603 +    }
   3.604 +
   3.605 +    if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0)) {
   3.606 +        *num_vfbs = 0;
   3.607 +        *num_vkbs = 0;
   3.608 +        *vfbs = NULL;
   3.609 +        *vkbs = NULL;
   3.610 +        while ((buf = xlu_cfg_get_listitem (cvfbs, *num_vfbs)) != NULL) {
   3.611 +            char *buf2 = strdup(buf);
   3.612 +            char *p, *p2;
   3.613 +            *vfbs = (libxl_device_vfb *) realloc(*vfbs, sizeof(libxl_device_vfb) * ((*num_vfbs) + 1));
   3.614 +            init_vfb_info((*vfbs) + (*num_vfbs), (*num_vfbs));
   3.615 +
   3.616 +            *vkbs = (libxl_device_vkb *) realloc(*vkbs, sizeof(libxl_device_vkb) * ((*num_vkbs) + 1));
   3.617 +            init_vkb_info((*vkbs) + (*num_vkbs), (*num_vkbs));
   3.618 +
   3.619 +            p = strtok(buf2, ",");
   3.620 +            if (!p)
   3.621 +                goto skip_vfb;
   3.622 +            do {
   3.623 +                while (*p == ' ')
   3.624 +                    p++;
   3.625 +                if ((p2 = strchr(p, '=')) == NULL)
   3.626 +                    break;
   3.627 +                *p2 = '\0';
   3.628 +                if (!strcmp(p, "vnc")) {
   3.629 +                    (*vfbs)[*num_vfbs].vnc = atoi(p2 + 1);
   3.630 +                } else if (!strcmp(p, "vnclisten")) {
   3.631 +                    (*vfbs)[*num_vfbs].vnclisten = strdup(p2 + 1);
   3.632 +                } else if (!strcmp(p, "vncdisplay")) {
   3.633 +                    (*vfbs)[*num_vfbs].vncdisplay = atoi(p2 + 1);
   3.634 +                } else if (!strcmp(p, "vncunused")) {
   3.635 +                    (*vfbs)[*num_vfbs].vncunused = atoi(p2 + 1);
   3.636 +                } else if (!strcmp(p, "keymap")) {
   3.637 +                    (*vfbs)[*num_vfbs].keymap = strdup(p2 + 1);
   3.638 +                } else if (!strcmp(p, "sdl")) {
   3.639 +                    (*vfbs)[*num_vfbs].sdl = atoi(p2 + 1);
   3.640 +                } else if (!strcmp(p, "opengl")) {
   3.641 +                    (*vfbs)[*num_vfbs].opengl = atoi(p2 + 1);
   3.642 +                } else if (!strcmp(p, "display")) {
   3.643 +                    (*vfbs)[*num_vfbs].display = strdup(p2 + 1);
   3.644 +                } else if (!strcmp(p, "xauthority")) {
   3.645 +                    (*vfbs)[*num_vfbs].xauthority = strdup(p2 + 1);
   3.646 +                }
   3.647 +            } while ((p = strtok(NULL, ",")) != NULL);
   3.648 +skip_vfb:
   3.649 +            free(buf2);
   3.650 +            *num_vfbs = (*num_vfbs) + 1;
   3.651 +            *num_vkbs = (*num_vkbs) + 1;
   3.652 +        }
   3.653 +    }
   3.654 +
   3.655 +    if (!xlu_cfg_get_long (config, "pci_msitranslate", &l))
   3.656 +        pci_msitranslate = l;
   3.657 +
   3.658 +    if (!xlu_cfg_get_long (config, "pci_power_mgmt", &l))
   3.659 +        pci_power_mgmt = l;
   3.660 +
   3.661 +    if (!xlu_cfg_get_list (config, "pci", &pcis, 0)) {
   3.662 +        *num_pcidevs = 0;
   3.663 +        *pcidevs = NULL;
   3.664 +        while ((buf = xlu_cfg_get_listitem (pcis, *num_pcidevs)) != NULL) {
   3.665 +            unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
   3.666 +            char *buf2 = strdup(buf);
   3.667 +            char *p;
   3.668 +            *pcidevs = (libxl_device_pci *) realloc(*pcidevs, sizeof (libxl_device_pci) * ((*num_pcidevs) + 1));
   3.669 +            memset(*pcidevs + *num_pcidevs, 0x00, sizeof(libxl_device_pci));
   3.670 +            p = strtok(buf2, ",");
   3.671 +            if (!p)
   3.672 +                goto skip_pci;
   3.673 +            if (!sscanf(p, PCI_BDF_VDEVFN, &domain, &bus, &dev, &func, &vdevfn)) {
   3.674 +                sscanf(p, "%02x:%02x.%01x@%02x", &bus, &dev, &func, &vdevfn);
   3.675 +                domain = 0;
   3.676 +            }
   3.677 +            libxl_device_pci_init(*pcidevs + *num_pcidevs, domain, bus, dev, func, vdevfn);
   3.678 +            (*pcidevs)[*num_pcidevs].msitranslate = pci_msitranslate;
   3.679 +            (*pcidevs)[*num_pcidevs].power_mgmt = pci_power_mgmt;
   3.680 +            while ((p = strtok(NULL, ",=")) != NULL) {
   3.681 +                while (*p == ' ')
   3.682 +                    p++;
   3.683 +                if (!strcmp(p, "msitranslate")) {
   3.684 +                    p = strtok(NULL, ",=");
   3.685 +                    (*pcidevs)[*num_pcidevs].msitranslate = atoi(p);
   3.686 +                } else if (!strcmp(p, "power_mgmt")) {
   3.687 +                    p = strtok(NULL, ",=");
   3.688 +                    (*pcidevs)[*num_pcidevs].power_mgmt = atoi(p);
   3.689 +                }
   3.690 +            }
   3.691 +            *num_pcidevs = (*num_pcidevs) + 1;
   3.692 +skip_pci:
   3.693 +            free(buf2);
   3.694 +        }
   3.695 +    }
   3.696 +
   3.697 +    if (c_info->hvm == 1) {
   3.698 +        /* init dm from c and b */
   3.699 +        init_dm_info(dm_info, c_info, b_info);
   3.700 +
   3.701 +        /* then process config related to dm */
   3.702 +        if (!xlu_cfg_get_string (config, "device_model", &buf))
   3.703 +            dm_info->device_model = strdup(buf);
   3.704 +        if (!xlu_cfg_get_long (config, "stdvga", &l))
   3.705 +            dm_info->stdvga = l;
   3.706 +        if (!xlu_cfg_get_long (config, "vnc", &l))
   3.707 +            dm_info->vnc = l;
   3.708 +        if (!xlu_cfg_get_string (config, "vnclisten", &buf))
   3.709 +            dm_info->vnclisten = strdup(buf);
   3.710 +        if (!xlu_cfg_get_long (config, "vncdisplay", &l))
   3.711 +            dm_info->vncdisplay = l;
   3.712 +        if (!xlu_cfg_get_long (config, "vncunused", &l))
   3.713 +            dm_info->vncunused = l;
   3.714 +        if (!xlu_cfg_get_string (config, "keymap", &buf))
   3.715 +            dm_info->keymap = strdup(buf);
   3.716 +        if (!xlu_cfg_get_long (config, "sdl", &l))
   3.717 +            dm_info->sdl = l;
   3.718 +        if (!xlu_cfg_get_long (config, "opengl", &l))
   3.719 +            dm_info->opengl = l;
   3.720 +        if (!xlu_cfg_get_long (config, "nographic", &l))
   3.721 +            dm_info->nographic = l;
   3.722 +        if (!xlu_cfg_get_string (config, "serial", &buf))
   3.723 +            dm_info->serial = strdup(buf);
   3.724 +        if (!xlu_cfg_get_string (config, "boot", &buf))
   3.725 +            dm_info->boot = strdup(buf);
   3.726 +        if (!xlu_cfg_get_long (config, "usb", &l))
   3.727 +            dm_info->usb = l;
   3.728 +        if (!xlu_cfg_get_string (config, "usbdevice", &buf))
   3.729 +            dm_info->usbdevice = strdup(buf);
   3.730 +    }
   3.731 +
   3.732 +    dm_info->type = c_info->hvm ? XENFV : XENPV;
   3.733 +
   3.734 +    xlu_cfg_destroy(config);
   3.735 +}
   3.736 +
   3.737 +#define CHK_ERRNO( call ) ({                                            \
   3.738 +        int chk_errno = (call);                                         \
   3.739 +        if (chk_errno) {                                                \
   3.740 +            fprintf(stderr,"xl: fatal error: %s:%d: %s: %s\n",          \
   3.741 +                    __FILE__,__LINE__, strerror(chk_errno), #call);     \
   3.742 +            exit(-ERROR_FAIL);                                          \
   3.743 +        }                                                               \
   3.744 +    })
   3.745 +
   3.746 +#define MUST( call ) ({                                                 \
   3.747 +        int must_rc = (call);                                           \
   3.748 +        if (must_rc) {                                                  \
   3.749 +            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: %s\n",       \
   3.750 +                    __FILE__,__LINE__, must_rc, #call);                 \
   3.751 +            exit(-must_rc);                                             \
   3.752 +        }                                                               \
   3.753 +    })
   3.754 +
   3.755 +static void *xmalloc(size_t sz) {
   3.756 +    void *r;
   3.757 +    r = malloc(sz);
   3.758 +    if (!r) { fprintf(stderr,"xl: Unable to malloc %lu bytes.\n",
   3.759 +                      (unsigned long)sz); exit(-ERROR_FAIL); }
   3.760 +    return r;
   3.761 +}
   3.762 +
   3.763 +static void *xrealloc(void *ptr, size_t sz) {
   3.764 +    void *r;
   3.765 +    if (!sz) { free(ptr); return 0; }
   3.766 +      /* realloc(non-0, 0) has a useless return value;
   3.767 +       * but xrealloc(anything, 0) is like free
   3.768 +       */
   3.769 +    r = realloc(ptr, sz);
   3.770 +    if (!r) { fprintf(stderr,"xl: Unable to realloc to %lu bytes.\n",
   3.771 +                      (unsigned long)sz); exit(-ERROR_FAIL); }
   3.772 +    return r;
   3.773 +}
   3.774 +
   3.775 +static int create_domain(int debug, int daemonize, const char *config_file, const char *restore_file, int paused, int migrate_fd /* -1 means none */, char **migration_domname_r)
   3.776 +{
   3.777 +    libxl_domain_create_info info1;
   3.778 +    libxl_domain_build_info info2;
   3.779 +    libxl_domain_build_state state;
   3.780 +    libxl_device_model_info dm_info;
   3.781 +    libxl_device_disk *disks = NULL;
   3.782 +    libxl_device_nic *vifs = NULL;
   3.783 +    libxl_device_pci *pcidevs = NULL;
   3.784 +    libxl_device_vfb *vfbs = NULL;
   3.785 +    libxl_device_vkb *vkbs = NULL;
   3.786 +    libxl_device_console console;
   3.787 +    int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 0;
   3.788 +    int i, fd;
   3.789 +    int need_daemon = 1;
   3.790 +    int ret, rc;
   3.791 +    libxl_device_model_starting *dm_starting = 0;
   3.792 +    libxl_waiter *w1 = NULL, *w2 = NULL;
   3.793 +    void *config_data = 0;
   3.794 +    int config_len = 0;
   3.795 +    int restore_fd = -1;
   3.796 +    struct save_file_header hdr;
   3.797 +
   3.798 +    memset(&dm_info, 0x00, sizeof(dm_info));
   3.799 +
   3.800 +    if (restore_file) {
   3.801 +        uint8_t *optdata_begin = 0;
   3.802 +        const uint8_t *optdata_here = 0;
   3.803 +        union { uint32_t u32; char b[4]; } u32buf;
   3.804 +        uint32_t badflags;
   3.805 +
   3.806 +        restore_fd = migrate_fd >= 0 ? migrate_fd :
   3.807 +            open(restore_file, O_RDONLY);
   3.808 +
   3.809 +        CHK_ERRNO( libxl_read_exactly(&ctx, restore_fd, &hdr,
   3.810 +                   sizeof(hdr), restore_file, "header") );
   3.811 +        if (memcmp(hdr.magic, savefileheader_magic, sizeof(hdr.magic))) {
   3.812 +            fprintf(stderr, "File has wrong magic number -"
   3.813 +                    " corrupt or for a different tool?\n");
   3.814 +            return ERROR_INVAL;
   3.815 +        }
   3.816 +        if (hdr.byteorder != SAVEFILE_BYTEORDER_VALUE) {
   3.817 +            fprintf(stderr, "File has wrong byte order\n");
   3.818 +            return ERROR_INVAL;
   3.819 +        }
   3.820 +        fprintf(stderr, "Loading new save file %s"
   3.821 +                " (new xl fmt info"
   3.822 +                " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n",
   3.823 +                restore_file, hdr.mandatory_flags, hdr.optional_flags,
   3.824 +                hdr.optional_data_len);
   3.825 +
   3.826 +        badflags = hdr.mandatory_flags & ~( 0 /* none understood yet */ );
   3.827 +        if (badflags) {
   3.828 +            fprintf(stderr, "Savefile has mandatory flag(s) 0x%"PRIx32" "
   3.829 +                    "which are not supported; need newer xl\n",
   3.830 +                    badflags);
   3.831 +            return ERROR_INVAL;
   3.832 +        }
   3.833 +        if (hdr.optional_data_len) {
   3.834 +            optdata_begin = xmalloc(hdr.optional_data_len);
   3.835 +            CHK_ERRNO( libxl_read_exactly(&ctx, restore_fd, optdata_begin,
   3.836 +                   hdr.optional_data_len, restore_file, "optdata") );
   3.837 +        }
   3.838 +
   3.839 +#define OPTDATA_LEFT  (hdr.optional_data_len - (optdata_here - optdata_begin))
   3.840 +#define WITH_OPTDATA(amt, body)                                 \
   3.841 +            if (OPTDATA_LEFT < (amt)) {                         \
   3.842 +                fprintf(stderr, "Savefile truncated.\n");       \
   3.843 +                return ERROR_INVAL;                             \
   3.844 +            } else {                                            \
   3.845 +                body;                                           \
   3.846 +                optdata_here += (amt);                          \
   3.847 +            }
   3.848 +
   3.849 +        optdata_here = optdata_begin;
   3.850 +
   3.851 +        if (OPTDATA_LEFT) {
   3.852 +            fprintf(stderr, " Savefile contains xl domain config\n");
   3.853 +            WITH_OPTDATA(4, {
   3.854 +                memcpy(u32buf.b, optdata_here, 4);
   3.855 +                config_len = u32buf.u32;
   3.856 +            });
   3.857 +            WITH_OPTDATA(config_len, {
   3.858 +                config_data = xmalloc(config_len);
   3.859 +                memcpy(config_data, optdata_here, config_len);
   3.860 +            });
   3.861 +        }
   3.862 +
   3.863 +    }
   3.864 +
   3.865 +    if (config_file) {
   3.866 +        free(config_data);  config_data = 0;
   3.867 +        ret = libxl_read_file_contents(&ctx, config_file,
   3.868 +                                       &config_data, &config_len);
   3.869 +        if (ret) { fprintf(stderr, "Failed to read config file: %s: %s\n",
   3.870 +                           config_file, strerror(errno)); return ERROR_FAIL; }
   3.871 +    } else {
   3.872 +        if (!config_data) {
   3.873 +            fprintf(stderr, "Config file not specified and"
   3.874 +                    " none in save file\n");
   3.875 +            return ERROR_INVAL;
   3.876 +        }
   3.877 +        config_file = "<saved>";
   3.878 +    }
   3.879 +
   3.880 +    printf("Parsing config file %s\n", config_file);
   3.881 +
   3.882 +    parse_config_data(config_file, config_data, config_len, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info);
   3.883 +
   3.884 +    if (migrate_fd >= 0) {
   3.885 +        if (info1.name) {
   3.886 +            /* when we receive a domain we get its name from the config
   3.887 +             * file; and we receive it to a temporary name */
   3.888 +            assert(!common_domname);
   3.889 +            common_domname = info1.name;
   3.890 +            asprintf(migration_domname_r, "%s--incoming", info1.name);
   3.891 +            info1.name = *migration_domname_r;
   3.892 +        }
   3.893 +    }
   3.894 +
   3.895 +    if (debug)
   3.896 +        printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info);
   3.897 +
   3.898 +start:
   3.899 +    domid = 0;
   3.900 +
   3.901 +    ret = libxl_domain_make(&ctx, &info1, &domid);
   3.902 +    if (ret) {
   3.903 +        fprintf(stderr, "cannot make domain: %d\n", ret);
   3.904 +        return ERROR_FAIL;
   3.905 +    }
   3.906 +
   3.907 +    ret = libxl_userdata_store(&ctx, domid, "xl",
   3.908 +                                    config_data, config_len);
   3.909 +    if (ret) {
   3.910 +        perror("cannot save config file");
   3.911 +        return ERROR_FAIL;
   3.912 +    }
   3.913 +
   3.914 +    if (!restore_file || !need_daemon) {
   3.915 +        if (dm_info.saved_state) {
   3.916 +            free(dm_info.saved_state);
   3.917 +            dm_info.saved_state = NULL;
   3.918 +        }
   3.919 +        ret = libxl_domain_build(&ctx, &info2, domid, &state);
   3.920 +    } else {
   3.921 +        ret = libxl_domain_restore(&ctx, &info2, domid, restore_fd, &state, &dm_info);
   3.922 +    }
   3.923 +
   3.924 +    if (ret) {
   3.925 +        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
   3.926 +        return ERROR_FAIL;
   3.927 +    }
   3.928 +
   3.929 +    for (i = 0; i < num_disks; i++) {
   3.930 +        disks[i].domid = domid;
   3.931 +        ret = libxl_device_disk_add(&ctx, domid, &disks[i]);
   3.932 +        if (ret) {
   3.933 +            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
   3.934 +            return ERROR_FAIL;
   3.935 +        }
   3.936 +    }
   3.937 +    for (i = 0; i < num_vifs; i++) {
   3.938 +        vifs[i].domid = domid;
   3.939 +        ret = libxl_device_nic_add(&ctx, domid, &vifs[i]);
   3.940 +        if (ret) {
   3.941 +            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
   3.942 +            return ERROR_FAIL;
   3.943 +        }
   3.944 +    }
   3.945 +    if (info1.hvm) {
   3.946 +        dm_info.domid = domid;
   3.947 +        MUST( libxl_create_device_model(&ctx, &dm_info, disks, num_disks,
   3.948 +                                        vifs, num_vifs, &dm_starting) );
   3.949 +    } else {
   3.950 +        for (i = 0; i < num_vfbs; i++) {
   3.951 +            vfbs[i].domid = domid;
   3.952 +            libxl_device_vfb_add(&ctx, domid, &vfbs[i]);
   3.953 +            vkbs[i].domid = domid;
   3.954 +            libxl_device_vkb_add(&ctx, domid, &vkbs[i]);
   3.955 +        }
   3.956 +        init_console_info(&console, 0, &state);
   3.957 +        console.domid = domid;
   3.958 +        if (num_vfbs)
   3.959 +            console.constype = CONSTYPE_IOEMU;
   3.960 +        libxl_device_console_add(&ctx, domid, &console);
   3.961 +        if (num_vfbs)
   3.962 +            libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console, &dm_starting);
   3.963 +    }
   3.964 +
   3.965 +    if (dm_starting)
   3.966 +        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
   3.967 +    for (i = 0; i < num_pcidevs; i++)
   3.968 +        libxl_device_pci_add(&ctx, domid, &pcidevs[i]);
   3.969 +
   3.970 +    if (!paused)
   3.971 +        libxl_domain_unpause(&ctx, domid);
   3.972 +
   3.973 +    if (!daemonize)
   3.974 +        return 0; /* caller gets success in parent */
   3.975 +
   3.976 +    if (need_daemon) {
   3.977 +        char *fullname, *name;
   3.978 +        pid_t child1, got_child;
   3.979 +        int nullfd;
   3.980 +
   3.981 +        child1 = libxl_fork(&ctx);
   3.982 +        if (child1) {
   3.983 +            int status;
   3.984 +            for (;;) {
   3.985 +                got_child = waitpid(child1, &status, 0);
   3.986 +                if (got_child == child1) break;
   3.987 +                assert(got_child == -1);
   3.988 +                if (errno != EINTR) {
   3.989 +                    perror("failed to wait for daemonizing child");
   3.990 +                    return ERROR_FAIL;
   3.991 +                }
   3.992 +            }
   3.993 +            if (status) {
   3.994 +                libxl_report_child_exitstatus(&ctx, XL_LOG_ERROR,
   3.995 +                           "daemonizing child", child1, status);
   3.996 +                return ERROR_FAIL;
   3.997 +            }
   3.998 +            return 0; /* caller gets success in parent */
   3.999 +        }
  3.1000 +
  3.1001 +        rc = libxl_ctx_postfork(&ctx);
  3.1002 +        if (rc) {
  3.1003 +            LOG("failed to reinitialise context after fork");
  3.1004 +            exit(-1);
  3.1005 +        }
  3.1006 +
  3.1007 +        asprintf(&name, "xl-%s", info1.name);
  3.1008 +        rc = libxl_create_logfile(&ctx, name, &fullname);
  3.1009 +        if (rc) {
  3.1010 +            LOG("failed to open logfile %s",fullname,strerror(errno));
  3.1011 +            exit(-1);
  3.1012 +        }
  3.1013 +
  3.1014 +        CHK_ERRNO(( logfile = open(fullname, O_WRONLY|O_CREAT, 0644) )<0);
  3.1015 +        free(fullname);
  3.1016 +        free(name);
  3.1017 +
  3.1018 +        CHK_ERRNO(( nullfd = open("/dev/null", O_RDONLY) )<0);
  3.1019 +        dup2(nullfd, 0);
  3.1020 +        dup2(logfile, 1);
  3.1021 +        dup2(logfile, 2);
  3.1022 +
  3.1023 +        daemon(0, 1);
  3.1024 +        need_daemon = 0;
  3.1025 +    }
  3.1026 +    LOG("Waiting for domain %s (domid %d) to die [pid %ld]",
  3.1027 +        info1.name, domid, (long)getpid());
  3.1028 +    w1 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter) * num_disks);
  3.1029 +    w2 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
  3.1030 +    libxl_wait_for_disk_ejects(&ctx, domid, disks, num_disks, w1);
  3.1031 +    libxl_wait_for_domain_death(&ctx, domid, w2);
  3.1032 +    libxl_get_wait_fd(&ctx, &fd);
  3.1033 +    while (1) {
  3.1034 +        int ret;
  3.1035 +        fd_set rfds;
  3.1036 +        xc_domaininfo_t info;
  3.1037 +        libxl_event event;
  3.1038 +        libxl_device_disk disk;
  3.1039 +        memset(&info, 0x00, sizeof(xc_dominfo_t));
  3.1040 +
  3.1041 +        FD_ZERO(&rfds);
  3.1042 +        FD_SET(fd, &rfds);
  3.1043 +
  3.1044 +        ret = select(fd + 1, &rfds, NULL, NULL, NULL);
  3.1045 +        if (!ret)
  3.1046 +            continue;
  3.1047 +        libxl_get_event(&ctx, &event);
  3.1048 +        switch (event.type) {
  3.1049 +            case DOMAIN_DEATH:
  3.1050 +                if (libxl_event_get_domain_death_info(&ctx, domid, &event, &info)) {
  3.1051 +                    LOG("Domain %d is dead", domid);
  3.1052 +                    if (info.flags & XEN_DOMINF_dying || (info.flags & XEN_DOMINF_shutdown && (((info.flags >> XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask) != SHUTDOWN_suspend))) {
  3.1053 +                        LOG("Domain %d needs to be clean: destroying the domain", domid);
  3.1054 +                        libxl_domain_destroy(&ctx, domid, 0);
  3.1055 +                        if (info.flags & XEN_DOMINF_shutdown &&
  3.1056 +                            (((info.flags >> XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask) == SHUTDOWN_reboot)) {
  3.1057 +                            libxl_free_waiter(w1);
  3.1058 +                            libxl_free_waiter(w2);
  3.1059 +                            free(w1);
  3.1060 +                            free(w2);
  3.1061 +                            LOG("Done. Rebooting now");
  3.1062 +                            goto start;
  3.1063 +                        }
  3.1064 +                        LOG("Done. Exiting now");
  3.1065 +                    }
  3.1066 +                    LOG("Domain %d does not need to be clean, exiting now", domid);
  3.1067 +                    exit(0);
  3.1068 +                }
  3.1069 +                break;
  3.1070 +            case DISK_EJECT:
  3.1071 +                if (libxl_event_get_disk_eject_info(&ctx, domid, &event, &disk))
  3.1072 +                    libxl_cdrom_insert(&ctx, domid, &disk);
  3.1073 +                break;
  3.1074 +        }
  3.1075 +        libxl_free_event(&event);
  3.1076 +    }
  3.1077 +
  3.1078 +    close(logfile);
  3.1079 +    exit(0);
  3.1080 +}
  3.1081 +
  3.1082 +void help(char *command)
  3.1083 +{
  3.1084 +    if (!command || !strcmp(command, "help")) {
  3.1085 +        printf("Usage xl <subcommand> [args]\n\n");
  3.1086 +        printf("xl full list of subcommands:\n\n");
  3.1087 +        printf(" create                        create a domain from config file <filename>\n\n");
  3.1088 +        printf(" list                          list information about all domains\n\n");
  3.1089 +        printf(" destroy                       terminate a domain immediately\n\n");
  3.1090 +        printf(" pci-attach                    insert a new pass-through pci device\n\n");
  3.1091 +        printf(" pci-detach                    remove a domain's pass-through pci device\n\n");
  3.1092 +        printf(" pci-list                      list pass-through pci devices for a domain\n\n");
  3.1093 +        printf(" pause                         pause execution of a domain\n\n");
  3.1094 +        printf(" unpause                       unpause a paused domain\n\n");
  3.1095 +        printf(" console                       attach to domain's console\n\n");
  3.1096 +        printf(" save                          save a domain state to restore later\n\n");
  3.1097 +        printf(" restore                       restore a domain from a saved state\n\n");
  3.1098 +        printf(" cd-insert                     insert a cdrom into a guest's cd drive\n\n");
  3.1099 +        printf(" cd-eject                      eject a cdrom from a guest's cd drive\n\n");
  3.1100 +        printf(" mem-set                       set the current memory usage for a domain\n\n");
  3.1101 +        printf(" button-press                  indicate an ACPI button press to the domain\n\n");
  3.1102 +        printf(" vcpu-list                     list the VCPUs for all/some domains.\n\n");
  3.1103 +        printf(" vcpu-pin                      Set which CPUs a VCPU can use.\n\n");
  3.1104 +        printf(" vcpu-set                      Set the number of active VCPUs allowed for the domain.\n\n");
  3.1105 +        printf(" sched-credit                  Get/set credit scheduler parameters.\n\n");
  3.1106 +    } else if(!strcmp(command, "create")) {
  3.1107 +        printf("Usage: xl create <ConfigFile> [options] [vars]\n\n");
  3.1108 +        printf("Create a domain based on <ConfigFile>.\n\n");
  3.1109 +        printf("Options:\n\n");
  3.1110 +        printf("-h                     Print this help.\n");
  3.1111 +        printf("-p                     Leave the domain paused after it is created.\n");
  3.1112 +        printf("-d                     Enable debug messages.\n");
  3.1113 +        printf("-e                     Do not wait in the background for the death of the domain.\n");
  3.1114 +    } else if(!strcmp(command, "list")) {
  3.1115 +        printf("Usage: xl list [-v] [Domain]\n\n");
  3.1116 +        printf("List information about all/some domains.\n\n");
  3.1117 +    } else if(!strcmp(command, "pci-attach")) {
  3.1118 +        printf("Usage: xl pci-attach <Domain> <BDF> [Virtual Slot]\n\n");
  3.1119 +        printf("Insert a new pass-through pci device.\n\n");
  3.1120 +    } else if(!strcmp(command, "pci-detach")) {
  3.1121 +        printf("Usage: xl pci-detach <Domain> <BDF>\n\n");
  3.1122 +        printf("Remove a domain's pass-through pci device.\n\n");
  3.1123 +    } else if(!strcmp(command, "pci-list")) {
  3.1124 +        printf("Usage: xl pci-list <Domain>\n\n");
  3.1125 +        printf("List pass-through pci devices for a domain.\n\n");
  3.1126 +    } else if(!strcmp(command, "pause")) {
  3.1127 +        printf("Usage: xl pause <Domain>\n\n");
  3.1128 +        printf("Pause execution of a domain.\n\n");
  3.1129 +    } else if(!strcmp(command, "unpause")) {
  3.1130 +        printf("Usage: xl unpause <Domain>\n\n");
  3.1131 +        printf("Unpause a paused domain.\n\n");
  3.1132 +    } else if(!strcmp(command, "save")) {
  3.1133 +        printf("Usage: xl save [options] <Domain> <CheckpointFile> [<ConfigFile>]\n\n");
  3.1134 +        printf("Save a domain state to restore later.\n\n");
  3.1135 +        printf("Options:\n\n");
  3.1136 +        printf("-h                     Print this help.\n");
  3.1137 +        printf("-c                     Leave domain running after creating the snapshot.\n");
  3.1138 +    } else if(!strcmp(command, "restore")) {
  3.1139 +        printf("Usage: xl restore [options] [<ConfigFile>] <CheckpointFile>\n\n");
  3.1140 +        printf("Restore a domain from a saved state.\n\n");
  3.1141 +        printf("Options:\n\n");
  3.1142 +        printf("-h                     Print this help.\n");
  3.1143 +        printf("-p                     Do not unpause domain after restoring it.\n");
  3.1144 +        printf("-e                     Do not wait in the background for the death of the domain.\n");
  3.1145 +        printf("-d                     Enable debug messages.\n");
  3.1146 +    } else if(!strcmp(command, "migrate")) {
  3.1147 +        printf("Usage: xl migrate [options] <Domain> <host>\n\n");
  3.1148 +        printf("Save a domain state to restore later.\n\n");
  3.1149 +        printf("Options:\n\n");
  3.1150 +        printf("-h                     Print this help.\n");
  3.1151 +        printf("-C <config>            Send <config> instead of config file from creation.\n");
  3.1152 +        printf("-s <sshcommand>        Use <sshcommand> instead of ssh.  String will be passed to sh.  If empty, run <host> instead of ssh <host> xl migrate-receive [-d -e]\n");
  3.1153 +        printf("-e                     Do not wait in the background (on <host>) for the death of the domain.\n");
  3.1154 +    } else if(!strcmp(command, "migrate-receive")) {
  3.1155 +        printf("Usage: xl migrate-receive  - for internal use only");
  3.1156 +    } else if(!strcmp(command, "restore")) {
  3.1157 +        printf("Usage: xl restore [options] [<ConfigFile>] <CheckpointFile>\n\n");
  3.1158 +        printf("Restore a domain from a saved state.\n\n");
  3.1159 +        printf("Options:\n\n");
  3.1160 +        printf("-h                     Print this help.\n");
  3.1161 +        printf("-O                     Old (configless) xl save format.\n");
  3.1162 +        printf("-p                     Do not unpause domain after restoring it.\n");
  3.1163 +        printf("-e                     Do not wait in the background for the death of the domain.\n");
  3.1164 +    } else if(!strcmp(command, "destroy")) {
  3.1165 +        printf("Usage: xl destroy <Domain>\n\n");
  3.1166 +        printf("Terminate a domain immediately.\n\n");
  3.1167 +    } else if (!strcmp(command, "console")) {
  3.1168 +        printf("Usage: xl console <Domain>\n\n");
  3.1169 +        printf("Attach to domain's console.\n\n");
  3.1170 +    } else if (!strcmp(command, "cd-insert")) {
  3.1171 +        printf("Usage: xl cd-insert <Domain> <VirtualDevice> <type:path>\n\n");
  3.1172 +        printf("Insert a cdrom into a guest's cd drive.\n\n");
  3.1173 +    } else if (!strcmp(command, "cd-eject")) {
  3.1174 +        printf("Usage: xl cd-eject <Domain> <VirtualDevice>\n\n");
  3.1175 +        printf("Eject a cdrom from a guest's cd drive.\n\n");
  3.1176 +    } else if (!strcmp(command, "mem-set")) {
  3.1177 +        printf("Usage: xl mem-set <Domain> <MemKB>\n\n");
  3.1178 +        printf("Set the current memory usage for a domain.\n\n");
  3.1179 +    } else if (!strcmp(command, "button-press")) {
  3.1180 +        printf("Usage: xl button-press <Domain> <Button>\n\n");
  3.1181 +        printf("Indicate <Button> press to a domain.\n");
  3.1182 +        printf("<Button> may be 'power' or 'sleep'.\n\n");
  3.1183 +    } else if (!strcmp(command, "vcpu-list")) {
  3.1184 +        printf("Usage: xl vcpu-list [Domain, ...]\n\n");
  3.1185 +        printf("List the VCPUs for all/some domains.\n\n");
  3.1186 +    } else if (!strcmp(command, "vcpu-pin")) {
  3.1187 +        printf("Usage: xl vcpu-pin <Domain> <VCPU|all> <CPUs|all>\n\n");
  3.1188 +        printf("Set which CPUs a VCPU can use.\n\n");
  3.1189 +    } else if (!strcmp(command, "vcpu-set")) {
  3.1190 +        printf("Usage: xl vcpu-set <Domain> <vCPUs>\n\n");
  3.1191 +        printf("Set the number of active VCPUs for allowed for the domain.\n\n");
  3.1192 +    } else if (!strcmp(command, "sched-credit")) {
  3.1193 +        printf("Usage: xl sched-credit [-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]\n\n");
  3.1194 +        printf("Get/set credit scheduler parameters.\n");
  3.1195 +        printf("  -d DOMAIN, --domain=DOMAIN     Domain to modify\n");
  3.1196 +        printf("  -w WEIGHT, --weight=WEIGHT     Weight (int)\n");
  3.1197 +        printf("  -c CAP, --cap=CAP              Cap (int)\n");
  3.1198 +    }
  3.1199 +}
  3.1200 +
  3.1201 +void set_memory_target(char *p, char *mem)
  3.1202 +{
  3.1203 +    char *endptr;
  3.1204 +    uint32_t memorykb;
  3.1205 +
  3.1206 +    find_domain(p);
  3.1207 +
  3.1208 +    memorykb = strtoul(mem, &endptr, 10);
  3.1209 +    if (*endptr != '\0') {
  3.1210 +        fprintf(stderr, "invalid memory size: %s\n", mem);
  3.1211 +        exit(3);
  3.1212 +    }
  3.1213 +    printf("setting domid %d memory to : %d\n", domid, memorykb);
  3.1214 +    libxl_set_memory_target(&ctx, domid, memorykb);
  3.1215 +}
  3.1216 +
  3.1217 +int main_memset(int argc, char **argv)
  3.1218 +{
  3.1219 +    int opt = 0;
  3.1220 +    char *p = NULL, *mem;
  3.1221 +
  3.1222 +    while ((opt = getopt(argc, argv, "h:")) != -1) {
  3.1223 +        switch (opt) {
  3.1224 +        case 'h':
  3.1225 +            help("mem-set");
  3.1226 +            exit(0);
  3.1227 +        default:
  3.1228 +            fprintf(stderr, "option not supported\n");
  3.1229 +            break;
  3.1230 +        }
  3.1231 +    }
  3.1232 +    if (optind >= argc - 1) {
  3.1233 +        help("mem-set");
  3.1234 +        exit(2);
  3.1235 +    }
  3.1236 +
  3.1237 +    p = argv[optind];
  3.1238 +    mem = argv[optind + 1];
  3.1239 +
  3.1240 +    set_memory_target(p, mem);
  3.1241 +    exit(0);
  3.1242 +}
  3.1243 +
  3.1244 +void console(char *p, int cons_num)
  3.1245 +{
  3.1246 +    find_domain(p);
  3.1247 +    libxl_console_attach(&ctx, domid, cons_num);
  3.1248 +}
  3.1249 +
  3.1250 +void cd_insert(char *dom, char *virtdev, char *phys)
  3.1251 +{
  3.1252 +    libxl_device_disk disk;
  3.1253 +    char *p;
  3.1254 +
  3.1255 +    find_domain(dom);
  3.1256 +
  3.1257 +    disk.backend_domid = 0;
  3.1258 +    disk.domid = domid;
  3.1259 +    if (phys) {
  3.1260 +        p = strchr(phys, ':');
  3.1261 +        if (!p) {
  3.1262 +            fprintf(stderr, "No type specified, ");
  3.1263 +            disk.physpath = phys;
  3.1264 +            if (!strncmp(phys, "/dev", 4)) {
  3.1265 +                fprintf(stderr, "assuming phy:\n");
  3.1266 +                disk.phystype = PHYSTYPE_PHY;
  3.1267 +            } else {
  3.1268 +                fprintf(stderr, "assuming file:\n");
  3.1269 +                disk.phystype = PHYSTYPE_FILE;
  3.1270 +            }
  3.1271 +        } else {
  3.1272 +            *p = '\0';
  3.1273 +            p++;
  3.1274 +            disk.physpath = p;
  3.1275 +            libxl_string_to_phystype(&ctx, phys, &disk.phystype);
  3.1276 +        }
  3.1277 +    } else {
  3.1278 +            disk.physpath = NULL;
  3.1279 +            disk.phystype = 0;
  3.1280 +    }
  3.1281 +    disk.virtpath = virtdev;
  3.1282 +    disk.unpluggable = 1;
  3.1283 +    disk.readwrite = 0;
  3.1284 +    disk.is_cdrom = 1;
  3.1285 +
  3.1286 +    libxl_cdrom_insert(&ctx, domid, &disk);
  3.1287 +}
  3.1288 +
  3.1289 +int main_cd_eject(int argc, char **argv)
  3.1290 +{
  3.1291 +    int opt = 0;
  3.1292 +    char *p = NULL, *virtdev;
  3.1293 +
  3.1294 +    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  3.1295 +        switch (opt) {
  3.1296 +        case 'h':
  3.1297 +            help("cd-eject");
  3.1298 +            exit(0);
  3.1299 +        default:
  3.1300 +            fprintf(stderr, "option not supported\n");
  3.1301 +            break;
  3.1302 +        }
  3.1303 +    }
  3.1304 +    if (optind >= argc - 1) {
  3.1305 +        help("cd-eject");
  3.1306 +        exit(2);
  3.1307 +    }
  3.1308 +
  3.1309 +    p = argv[optind];
  3.1310 +    virtdev = argv[optind + 1];
  3.1311 +
  3.1312 +    cd_insert(p, virtdev, NULL);
  3.1313 +    exit(0);
  3.1314 +}
  3.1315 +
  3.1316 +int main_cd_insert(int argc, char **argv)
  3.1317 +{
  3.1318 +    int opt = 0;
  3.1319 +    char *p = NULL, *file = NULL, *virtdev;
  3.1320 +
  3.1321 +    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  3.1322 +        switch (opt) {
  3.1323 +        case 'h':
  3.1324 +            help("cd-insert");
  3.1325 +            exit(0);
  3.1326 +        default:
  3.1327 +            fprintf(stderr, "option not supported\n");
  3.1328 +            break;
  3.1329 +        }
  3.1330 +    }
  3.1331 +    if (optind >= argc - 2) {
  3.1332 +        help("cd-insert");
  3.1333 +        exit(2);
  3.1334 +    }
  3.1335 +
  3.1336 +    p = argv[optind];
  3.1337 +    virtdev = argv[optind + 1];
  3.1338 +    file = argv[optind + 2];
  3.1339 +
  3.1340 +    cd_insert(p, virtdev, file);
  3.1341 +    exit(0);
  3.1342 +}
  3.1343 +
  3.1344 +int main_console(int argc, char **argv)
  3.1345 +{
  3.1346 +    int opt = 0, cons_num = 0;
  3.1347 +    char *p = NULL;
  3.1348 +
  3.1349 +    while ((opt = getopt(argc, argv, "hn:")) != -1) {
  3.1350 +        switch (opt) {
  3.1351 +        case 'h':
  3.1352 +            help("console");
  3.1353 +            exit(0);
  3.1354 +        case 'n':
  3.1355 +            if (optarg) {
  3.1356 +                cons_num = strtol(optarg, NULL, 10);
  3.1357 +            }
  3.1358 +            break;
  3.1359 +        default:
  3.1360 +            fprintf(stderr, "option not supported\n");
  3.1361 +            break;
  3.1362 +        }
  3.1363 +    }
  3.1364 +    if (optind >= argc) {
  3.1365 +        help("console");
  3.1366 +        exit(2);
  3.1367 +    }
  3.1368 +
  3.1369 +    p = argv[optind];
  3.1370 +
  3.1371 +    console(p, cons_num);
  3.1372 +    exit(0);
  3.1373 +}
  3.1374 +
  3.1375 +void pcilist(char *dom)
  3.1376 +{
  3.1377 +    libxl_device_pci *pcidevs;
  3.1378 +    int num, i;
  3.1379 +
  3.1380 +    find_domain(dom);
  3.1381 +
  3.1382 +    pcidevs = libxl_device_pci_list(&ctx, domid, &num);
  3.1383 +    if (!num)
  3.1384 +        return;
  3.1385 +    printf("VFn  domain bus  slot func\n");
  3.1386 +    for (i = 0; i < num; i++) {
  3.1387 +        printf("0x%02x 0x%04x 0x%02x 0x%02x 0x%01x\n", pcidevs[i].vdevfn, pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
  3.1388 +    }
  3.1389 +    free(pcidevs);
  3.1390 +}
  3.1391 +
  3.1392 +int main_pcilist(int argc, char **argv)
  3.1393 +{
  3.1394 +    int opt;
  3.1395 +    char *domname = NULL;
  3.1396 +
  3.1397 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.1398 +        switch (opt) {
  3.1399 +        case 'h':
  3.1400 +            help("pci-list");
  3.1401 +            exit(0);
  3.1402 +        default:
  3.1403 +            fprintf(stderr, "option not supported\n");
  3.1404 +            break;
  3.1405 +        }
  3.1406 +    }
  3.1407 +    if (optind >= argc) {
  3.1408 +        help("pci-list");
  3.1409 +        exit(2);
  3.1410 +    }
  3.1411 +
  3.1412 +    domname = argv[optind];
  3.1413 +
  3.1414 +    pcilist(domname);
  3.1415 +    exit(0);
  3.1416 +}
  3.1417 +
  3.1418 +void pcidetach(char *dom, char *bdf)
  3.1419 +{
  3.1420 +    libxl_device_pci pcidev;
  3.1421 +    unsigned int domain, bus, dev, func;
  3.1422 +
  3.1423 +    find_domain(dom);
  3.1424 +
  3.1425 +    memset(&pcidev, 0x00, sizeof(pcidev));
  3.1426 +    sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func);
  3.1427 +    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
  3.1428 +    libxl_device_pci_remove(&ctx, domid, &pcidev);
  3.1429 +}
  3.1430 +
  3.1431 +int main_pcidetach(int argc, char **argv)
  3.1432 +{
  3.1433 +    int opt;
  3.1434 +    char *domname = NULL, *bdf = NULL;
  3.1435 +
  3.1436 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.1437 +        switch (opt) {
  3.1438 +        case 'h':
  3.1439 +            help("pci-attach");
  3.1440 +            exit(0);
  3.1441 +        default:
  3.1442 +            fprintf(stderr, "option not supported\n");
  3.1443 +            break;
  3.1444 +        }
  3.1445 +    }
  3.1446 +    if (optind >= argc - 1) {
  3.1447 +        help("pci-detach");
  3.1448 +        exit(2);
  3.1449 +    }
  3.1450 +
  3.1451 +    domname = argv[optind];
  3.1452 +    bdf = argv[optind + 1];
  3.1453 +
  3.1454 +    pcidetach(domname, bdf);
  3.1455 +    exit(0);
  3.1456 +}
  3.1457 +void pciattach(char *dom, char *bdf, char *vs)
  3.1458 +{
  3.1459 +    libxl_device_pci pcidev;
  3.1460 +    unsigned int domain, bus, dev, func;
  3.1461 +
  3.1462 +    find_domain(dom);
  3.1463 +
  3.1464 +    memset(&pcidev, 0x00, sizeof(pcidev));
  3.1465 +    sscanf(bdf, PCI_BDF, &domain, &bus, &dev, &func);
  3.1466 +    libxl_device_pci_init(&pcidev, domain, bus, dev, func, 0);
  3.1467 +    libxl_device_pci_add(&ctx, domid, &pcidev);
  3.1468 +}
  3.1469 +
  3.1470 +int main_pciattach(int argc, char **argv)
  3.1471 +{
  3.1472 +    int opt;
  3.1473 +    char *domname = NULL, *bdf = NULL, *vs = NULL;
  3.1474 +
  3.1475 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.1476 +        switch (opt) {
  3.1477 +        case 'h':
  3.1478 +            help("pci-attach");
  3.1479 +            exit(0);
  3.1480 +        default:
  3.1481 +            fprintf(stderr, "option not supported\n");
  3.1482 +            break;
  3.1483 +        }
  3.1484 +    }
  3.1485 +    if (optind >= argc - 1) {
  3.1486 +        help("pci-attach");
  3.1487 +        exit(2);
  3.1488 +    }
  3.1489 +
  3.1490 +    domname = argv[optind];
  3.1491 +    bdf = argv[optind + 1];
  3.1492 +
  3.1493 +    if (optind + 1 < argc)
  3.1494 +        vs = argv[optind + 2];
  3.1495 +
  3.1496 +    pciattach(domname, bdf, vs);
  3.1497 +    exit(0);
  3.1498 +}
  3.1499 +
  3.1500 +void pause_domain(char *p)
  3.1501 +{
  3.1502 +    find_domain(p);
  3.1503 +    libxl_domain_pause(&ctx, domid);
  3.1504 +}
  3.1505 +
  3.1506 +void unpause_domain(char *p)
  3.1507 +{
  3.1508 +    find_domain(p);
  3.1509 +    libxl_domain_unpause(&ctx, domid);
  3.1510 +}
  3.1511 +
  3.1512 +void destroy_domain(char *p)
  3.1513 +{
  3.1514 +    int rc;
  3.1515 +    find_domain(p);
  3.1516 +    rc = libxl_domain_destroy(&ctx, domid, 0);
  3.1517 +    if (rc) { fprintf(stderr,"destroy failed (rc=%d)\n.",rc); exit(-1); }
  3.1518 +}
  3.1519 +
  3.1520 +void list_domains(int verbose)
  3.1521 +{
  3.1522 +    struct libxl_dominfo *info;
  3.1523 +    int nb_domain, i;
  3.1524 +
  3.1525 +    info = libxl_list_domain(&ctx, &nb_domain);
  3.1526 +
  3.1527 +    if (!info) {
  3.1528 +        fprintf(stderr, "libxl_domain_infolist failed.\n");
  3.1529 +        exit(1);
  3.1530 +    }
  3.1531 +    printf("Name                                        ID   Mem VCPUs\tState\tTime(s)\n");
  3.1532 +    for (i = 0; i < nb_domain; i++) {
  3.1533 +        printf("%-40s %5d %5lu %5d        %c%c%c %8.1f",
  3.1534 +                libxl_domid_to_name(&ctx, info[i].domid),
  3.1535 +                info[i].domid,
  3.1536 +                (unsigned long) (info[i].max_memkb / 1024),
  3.1537 +                info[i].vcpu_online,
  3.1538 +                info[i].running ? 'r' : '-',
  3.1539 +                info[i].paused ? 'p' : '-',
  3.1540 +                info[i].dying ? 'd' : '-',
  3.1541 +                ((float)info[i].cpu_time / 1e9));
  3.1542 +        if (verbose) {
  3.1543 +            char *uuid = libxl_uuid2string(&ctx, info[i].uuid);
  3.1544 +            printf(" %s", uuid);
  3.1545 +        }
  3.1546 +        putchar('\n');
  3.1547 +    }
  3.1548 +    free(info);
  3.1549 +}
  3.1550 +
  3.1551 +void list_vm(void)
  3.1552 +{
  3.1553 +    struct libxl_vminfo *info;
  3.1554 +    int nb_vm, i;
  3.1555 +
  3.1556 +    info = libxl_list_vm(&ctx, &nb_vm);
  3.1557 +
  3.1558 +    if (info < 0) {
  3.1559 +        fprintf(stderr, "libxl_domain_infolist failed.\n");
  3.1560 +        exit(1);
  3.1561 +    }
  3.1562 +    printf("UUID                                  ID    name\n");
  3.1563 +    for (i = 0; i < nb_vm; i++) {
  3.1564 +        printf(UUID_FMT "  %d    %-30s\n",
  3.1565 +            info[i].uuid[0], info[i].uuid[1], info[i].uuid[2], info[i].uuid[3],
  3.1566 +            info[i].uuid[4], info[i].uuid[5], info[i].uuid[6], info[i].uuid[7],
  3.1567 +            info[i].uuid[8], info[i].uuid[9], info[i].uuid[10], info[i].uuid[11],
  3.1568 +            info[i].uuid[12], info[i].uuid[13], info[i].uuid[14], info[i].uuid[15],
  3.1569 +            info[i].domid, libxl_domid_to_name(&ctx, info[i].domid));
  3.1570 +    }
  3.1571 +    free(info);
  3.1572 +}
  3.1573 +
  3.1574 +static void save_domain_core_begin(char *domain_spec,
  3.1575 +                                   const char *override_config_file,
  3.1576 +                                   uint8_t **config_data_r,
  3.1577 +                                   int *config_len_r)
  3.1578 +{
  3.1579 +    int rc;
  3.1580 +
  3.1581 +    find_domain(domain_spec);
  3.1582 +
  3.1583 +    /* configuration file in optional data: */
  3.1584 +
  3.1585 +    if (override_config_file) {
  3.1586 +        void *config_v = 0;
  3.1587 +        rc = libxl_read_file_contents(&ctx, override_config_file,
  3.1588 +                                      &config_v, config_len_r);
  3.1589 +        *config_data_r = config_v;
  3.1590 +    } else {
  3.1591 +        rc = libxl_userdata_retrieve(&ctx, domid, "xl",
  3.1592 +                                     config_data_r, config_len_r);
  3.1593 +    }
  3.1594 +    if (rc) {
  3.1595 +        fputs("Unable to get config file\n",stderr);
  3.1596 +        exit(2);
  3.1597 +    }
  3.1598 +}
  3.1599 +
  3.1600 +void save_domain_core_writeconfig(int fd, const char *filename,
  3.1601 +                                  const uint8_t *config_data, int config_len)
  3.1602 +{
  3.1603 +    struct save_file_header hdr;
  3.1604 +    uint8_t *optdata_begin;
  3.1605 +    union { uint32_t u32; char b[4]; } u32buf;
  3.1606 +
  3.1607 +    memset(&hdr, 0, sizeof(hdr));
  3.1608 +    memcpy(hdr.magic, savefileheader_magic, sizeof(hdr.magic));
  3.1609 +    hdr.byteorder = SAVEFILE_BYTEORDER_VALUE;
  3.1610 +
  3.1611 +    optdata_begin= 0;
  3.1612 +
  3.1613 +#define ADD_OPTDATA(ptr, len) ({                                            \
  3.1614 +    if ((len)) {                                                        \
  3.1615 +        hdr.optional_data_len += (len);                                 \
  3.1616 +        optdata_begin = xrealloc(optdata_begin, hdr.optional_data_len); \
  3.1617 +        memcpy(optdata_begin + hdr.optional_data_len - (len),           \
  3.1618 +               (ptr), (len));                                           \
  3.1619 +    }                                                                   \
  3.1620 +                          })
  3.1621 +
  3.1622 +    u32buf.u32 = config_len;
  3.1623 +    ADD_OPTDATA(u32buf.b,    4);
  3.1624 +    ADD_OPTDATA(config_data, config_len);
  3.1625 +
  3.1626 +    /* that's the optional data */
  3.1627 +
  3.1628 +    CHK_ERRNO( libxl_write_exactly(&ctx, fd,
  3.1629 +        &hdr, sizeof(hdr), filename, "header") );
  3.1630 +    CHK_ERRNO( libxl_write_exactly(&ctx, fd,
  3.1631 +        optdata_begin, hdr.optional_data_len, filename, "header") );
  3.1632 +
  3.1633 +    fprintf(stderr, "Saving to %s new xl format (info"
  3.1634 +            " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n",
  3.1635 +            filename, hdr.mandatory_flags, hdr.optional_flags,
  3.1636 +            hdr.optional_data_len);
  3.1637 +}
  3.1638 +
  3.1639 +int save_domain(char *p, char *filename, int checkpoint,
  3.1640 +                const char *override_config_file)
  3.1641 +{
  3.1642 +    int fd;
  3.1643 +    uint8_t *config_data;
  3.1644 +    int config_len;
  3.1645 +
  3.1646 +    save_domain_core_begin(p, override_config_file, &config_data, &config_len);
  3.1647 +
  3.1648 +    if (!config_len) {
  3.1649 +        fputs(" Savefile will not contain xl domain config\n", stderr);
  3.1650 +    }
  3.1651 +
  3.1652 +    fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
  3.1653 +    if (fd < 0) {
  3.1654 +        fprintf(stderr, "Failed to open temp file %s for writing\n", filename);
  3.1655 +        exit(2);
  3.1656 +    }
  3.1657 +
  3.1658 +    save_domain_core_writeconfig(fd, filename, config_data, config_len);
  3.1659 +
  3.1660 +    libxl_domain_suspend(&ctx, NULL, domid, fd);
  3.1661 +    close(fd);
  3.1662 +
  3.1663 +    if (checkpoint)
  3.1664 +        libxl_domain_unpause(&ctx, domid);
  3.1665 +    else
  3.1666 +        libxl_domain_destroy(&ctx, domid, 0);
  3.1667 +
  3.1668 +    exit(0);
  3.1669 +}
  3.1670 +
  3.1671 +static int migrate_read_fixedmessage(int fd, const void *msg, int msgsz,
  3.1672 +                                     const char *what, const char *rune) {
  3.1673 +    char buf[msgsz];
  3.1674 +    const char *stream;
  3.1675 +    int rc;
  3.1676 +
  3.1677 +    stream = rune ? "migration receiver stream" : "migration stream";
  3.1678 +    rc = libxl_read_exactly(&ctx, fd, buf, msgsz, stream, what);
  3.1679 +    if (rc) return ERROR_FAIL;
  3.1680 +
  3.1681 +    if (memcmp(buf, msg, msgsz)) {
  3.1682 +        fprintf(stderr, "%s contained unexpected data instead of %s\n",
  3.1683 +                stream, what);
  3.1684 +        if (rune)
  3.1685 +            fprintf(stderr, "(command run was: %s )\n", rune);
  3.1686 +        return ERROR_FAIL;
  3.1687 +    }
  3.1688 +    return 0;
  3.1689 +}
  3.1690 +
  3.1691 +static void migration_child_report(pid_t migration_child, int recv_fd) {
  3.1692 +    pid_t child;
  3.1693 +    int status, sr;
  3.1694 +    struct timeval now, waituntil, timeout;
  3.1695 +    static const struct timeval pollinterval = { 0, 1000 }; /* 1ms */
  3.1696 +
  3.1697 +    if (!migration_child) return;
  3.1698 +
  3.1699 +    CHK_ERRNO( gettimeofday(&waituntil, 0) );
  3.1700 +    waituntil.tv_sec += 2;
  3.1701 +
  3.1702 +    for (;;) {
  3.1703 +        child = waitpid(migration_child, &status, WNOHANG);
  3.1704 +
  3.1705 +        if (child == migration_child) {
  3.1706 +            if (status)
  3.1707 +                libxl_report_child_exitstatus(&ctx, XL_LOG_INFO,
  3.1708 +                                              "migration target process",
  3.1709 +                                              migration_child, status);
  3.1710 +            break;
  3.1711 +        }
  3.1712 +        if (child == -1) {
  3.1713 +            if (errno == EINTR) continue;
  3.1714 +            fprintf(stderr, "wait for migration child [%ld] failed: %s\n",
  3.1715 +                    (long)migration_child, strerror(errno));
  3.1716 +            break;
  3.1717 +        }
  3.1718 +        assert(child == 0);
  3.1719 +
  3.1720 +        CHK_ERRNO( gettimeofday(&now, 0) );
  3.1721 +        if (timercmp(&now, &waituntil, >)) {
  3.1722 +            fprintf(stderr, "migration child [%ld] not exiting, no longer"
  3.1723 +                    " waiting (exit status will be unreported)\n",
  3.1724 +                    (long)migration_child);
  3.1725 +            break;
  3.1726 +        }
  3.1727 +        timersub(&waituntil, &now, &timeout);
  3.1728 +
  3.1729 +        if (recv_fd >= 0) {
  3.1730 +            fd_set readfds, exceptfds;
  3.1731 +            FD_ZERO(&readfds);
  3.1732 +            FD_ZERO(&exceptfds);
  3.1733 +            FD_SET(recv_fd, &readfds);
  3.1734 +            FD_SET(recv_fd, &exceptfds);
  3.1735 +            sr = select(recv_fd+1, &readfds,0,&exceptfds, &timeout);
  3.1736 +        } else {
  3.1737 +            if (timercmp(&timeout, &pollinterval, >))
  3.1738 +                timeout = pollinterval;
  3.1739 +            sr = select(0,0,0,0, &timeout);
  3.1740 +        }
  3.1741 +        if (sr > 0) {
  3.1742 +            recv_fd = -1;
  3.1743 +        } else if (sr == 0) {
  3.1744 +        } else if (sr == -1) {
  3.1745 +            if (errno != EINTR) {
  3.1746 +                fprintf(stderr, "migration child [%ld] exit wait select"
  3.1747 +                        " failed unexpectedly: %s\n",
  3.1748 +                        (long)migration_child, strerror(errno));
  3.1749 +                break;
  3.1750 +            }
  3.1751 +        }
  3.1752 +    }
  3.1753 +    migration_child = 0;
  3.1754 +}
  3.1755 +
  3.1756 +static void migrate_domain(char *domain_spec, const char *rune,
  3.1757 +                           const char *override_config_file)
  3.1758 +{
  3.1759 +    pid_t child = -1;
  3.1760 +    int rc;
  3.1761 +    int sendpipe[2], recvpipe[2];
  3.1762 +    int send_fd, recv_fd;
  3.1763 +    libxl_domain_suspend_info suspinfo;
  3.1764 +    char *away_domname;
  3.1765 +    char rc_buf;
  3.1766 +    uint8_t *config_data;
  3.1767 +    int config_len;
  3.1768 +
  3.1769 +    save_domain_core_begin(domain_spec, override_config_file,
  3.1770 +                           &config_data, &config_len);
  3.1771 +
  3.1772 +    if (!common_domname) {
  3.1773 +        common_domname = libxl_domid_to_name(&ctx, domid);
  3.1774 +        /* libxl_domid_to_name fails ?  don't bother with names then */
  3.1775 +    }
  3.1776 +
  3.1777 +    if (!config_len) {
  3.1778 +        fprintf(stderr, "No config file stored for running domain and "
  3.1779 +                "none supplied - cannot migrate.\n");
  3.1780 +        exit(1);
  3.1781 +    }
  3.1782 +
  3.1783 +    MUST( libxl_pipe(&ctx, sendpipe) );
  3.1784 +    MUST( libxl_pipe(&ctx, recvpipe) );
  3.1785 +
  3.1786 +    child = libxl_fork(&ctx);
  3.1787 +    if (child==-1) exit(1);
  3.1788 +
  3.1789 +    if (!child) {
  3.1790 +        dup2(sendpipe[0], 0);
  3.1791 +        dup2(recvpipe[1], 1);
  3.1792 +        close(sendpipe[0]); close(sendpipe[1]);
  3.1793 +        close(recvpipe[0]); close(recvpipe[1]);
  3.1794 +        execlp("sh","sh","-c",rune,(char*)0);
  3.1795 +        perror("failed to exec sh");
  3.1796 +        exit(-1);
  3.1797 +    }
  3.1798 +
  3.1799 +    close(sendpipe[0]);
  3.1800 +    close(recvpipe[1]);
  3.1801 +    send_fd = sendpipe[1];
  3.1802 +    recv_fd = recvpipe[0];
  3.1803 +
  3.1804 +    signal(SIGPIPE, SIG_IGN);
  3.1805 +    /* if receiver dies, we get an error and can clean up
  3.1806 +       rather than just dying */
  3.1807 +
  3.1808 +    rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_banner,
  3.1809 +                                   sizeof(migrate_receiver_banner)-1,
  3.1810 +                                   "banner", rune);
  3.1811 +    if (rc) {
  3.1812 +        close(send_fd);
  3.1813 +        migration_child_report(child, recv_fd);
  3.1814 +        exit(-rc);
  3.1815 +    }
  3.1816 +
  3.1817 +    save_domain_core_writeconfig(send_fd, "migration stream",
  3.1818 +                                 config_data, config_len);
  3.1819 +
  3.1820 +    memset(&suspinfo, 0, sizeof(suspinfo));
  3.1821 +    suspinfo.flags |= XL_SUSPEND_LIVE;
  3.1822 +    rc = libxl_domain_suspend(&ctx, &suspinfo, domid, send_fd);
  3.1823 +    if (rc) {
  3.1824 +        fprintf(stderr, "migration sender: libxl_domain_suspend failed"
  3.1825 +                " (rc=%d)\n", rc);
  3.1826 +        goto failed_resume;
  3.1827 +    }
  3.1828 +
  3.1829 +    fprintf(stderr, "migration sender: Transfer complete.\n");
  3.1830 +
  3.1831 +    rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_ready,
  3.1832 +                                   sizeof(migrate_receiver_ready),
  3.1833 +                                   "ready message", rune);
  3.1834 +    if (rc) goto failed_resume;
  3.1835 +
  3.1836 +    /* right, at this point we are about give the destination
  3.1837 +     * permission to rename and resume, so we must first rename the
  3.1838 +     * domain away ourselves */
  3.1839 +
  3.1840 +    fprintf(stderr, "migration sender: Target has acknowledged transfer.\n");
  3.1841 +
  3.1842 +    if (common_domname) {
  3.1843 +        asprintf(&away_domname, "%s--migratedaway", common_domname);
  3.1844 +        rc = libxl_domain_rename(&ctx, domid,
  3.1845 +                                 common_domname, away_domname, 0);
  3.1846 +        if (rc) goto failed_resume;
  3.1847 +    }
  3.1848 +
  3.1849 +    /* point of no return - as soon as we have tried to say
  3.1850 +     * "go" to the receiver, it's not safe to carry on.  We leave
  3.1851 +     * the domain renamed to %s--migratedaway in case that's helpful.
  3.1852 +     */
  3.1853 +
  3.1854 +    fprintf(stderr, "migration sender: Giving target permission to start.\n");
  3.1855 +
  3.1856 +    rc = libxl_write_exactly(&ctx, send_fd,
  3.1857 +                             migrate_permission_to_go,
  3.1858 +                             sizeof(migrate_permission_to_go),
  3.1859 +                             "migration stream", "GO message");
  3.1860 +    if (rc) goto failed_badly;
  3.1861 +
  3.1862 +    rc = migrate_read_fixedmessage(recv_fd, migrate_report,
  3.1863 +                                   sizeof(migrate_report),
  3.1864 +                                   "success/failure report message", rune);
  3.1865 +    if (rc) goto failed_badly;
  3.1866 +
  3.1867 +    rc = libxl_read_exactly(&ctx, recv_fd,
  3.1868 +                            &rc_buf, 1,
  3.1869 +                            "migration ack stream", "success/failure status");
  3.1870 +    if (rc) goto failed_badly;
  3.1871 +
  3.1872 +    if (rc_buf) {
  3.1873 +        fprintf(stderr, "migration sender: Target reports startup failure"
  3.1874 +                " (status code %d).\n", rc_buf);
  3.1875 +
  3.1876 +        rc = migrate_read_fixedmessage(recv_fd, migrate_permission_to_go,
  3.1877 +                                       sizeof(migrate_permission_to_go),
  3.1878 +                                       "permission for sender to resume",
  3.1879 +                                       rune);
  3.1880 +        if (rc) goto failed_badly;
  3.1881 +
  3.1882 +        fprintf(stderr, "migration sender: Trying to resume at our end.\n");
  3.1883 +
  3.1884 +        if (common_domname) {
  3.1885 +            libxl_domain_rename(&ctx, domid,
  3.1886 +                                away_domname, common_domname, 0);
  3.1887 +        }
  3.1888 +        rc = libxl_domain_resume(&ctx, domid);
  3.1889 +        if (!rc) fprintf(stderr, "migration sender: Resumed OK.\n");
  3.1890 +
  3.1891 +        fprintf(stderr, "Migration failed due to problems at target.\n");
  3.1892 +        exit(-ERROR_FAIL);
  3.1893 +    }
  3.1894 +
  3.1895 +    fprintf(stderr, "migration sender: Target reports successful startup.\n");
  3.1896 +    libxl_domain_destroy(&ctx, domid, 1); /* bang! */
  3.1897 +    fprintf(stderr, "Migration successful.\n");
  3.1898 +    exit(0);
  3.1899 +
  3.1900 + failed_resume:
  3.1901 +    close(send_fd);
  3.1902 +    migration_child_report(child, recv_fd);
  3.1903 +    fprintf(stderr, "Migration failed, resuming at sender.\n");
  3.1904 +    libxl_domain_resume(&ctx, domid);
  3.1905 +    exit(-ERROR_FAIL);
  3.1906 +
  3.1907 + failed_badly:
  3.1908 +    fprintf(stderr,
  3.1909 + "** Migration failed during final handshake **\n"
  3.1910 + "Domain state is now undefined !\n"
  3.1911 + "Please CHECK AT BOTH ENDS for running instances, before renaming and\n"
  3.1912 + " resuming at most one instance.  Two simultaneous instances of the domain\n"
  3.1913 + " would probably result in SEVERE DATA LOSS and it is now your\n"
  3.1914 + " responsibility to avoid that.  Sorry.\n");
  3.1915 +
  3.1916 +    close(send_fd);
  3.1917 +    migration_child_report(child, recv_fd);
  3.1918 +    exit(-ERROR_BADFAIL);
  3.1919 +}
  3.1920 +
  3.1921 +static void migrate_receive(int debug, int daemonize)
  3.1922 +{
  3.1923 +    int rc, rc2;
  3.1924 +    char rc_buf;
  3.1925 +    char *migration_domname;
  3.1926 +
  3.1927 +    signal(SIGPIPE, SIG_IGN);
  3.1928 +    /* if we get SIGPIPE we'd rather just have it as an error */
  3.1929 +
  3.1930 +    fprintf(stderr, "migration target: Ready to receive domain.\n");
  3.1931 +
  3.1932 +    CHK_ERRNO( libxl_write_exactly(&ctx, 1,
  3.1933 +                                   migrate_receiver_banner,
  3.1934 +                                   sizeof(migrate_receiver_banner)-1,
  3.1935 +                                   "migration ack stream",
  3.1936 +                                   "banner") );
  3.1937 +
  3.1938 +    rc = create_domain(debug, daemonize,
  3.1939 +                       0 /* no config file, use incoming */,
  3.1940 +                       "incoming migration stream", 1,
  3.1941 +                       0, &migration_domname);
  3.1942 +    if (rc) {
  3.1943 +        fprintf(stderr, "migration target: Domain creation failed"
  3.1944 +                " (code %d).\n", rc);
  3.1945 +        exit(-rc);
  3.1946 +    }
  3.1947 +
  3.1948 +    fprintf(stderr, "migration target: Transfer complete,"
  3.1949 +            " requesting permission to start domain.\n");
  3.1950 +
  3.1951 +    rc = libxl_write_exactly(&ctx, 1,
  3.1952 +                             migrate_receiver_ready,
  3.1953 +                             sizeof(migrate_receiver_ready),
  3.1954 +                             "migration ack stream", "ready message");
  3.1955 +    if (rc) exit(-rc);
  3.1956 +
  3.1957 +    rc = migrate_read_fixedmessage(0, migrate_permission_to_go,
  3.1958 +                                   sizeof(migrate_permission_to_go),
  3.1959 +                                   "GO message", 0);
  3.1960 +    if (rc) goto perhaps_destroy_notify_rc;
  3.1961 +
  3.1962 +    fprintf(stderr, "migration target: Got permission, starting domain.\n");
  3.1963 +
  3.1964 +    if (migration_domname) {
  3.1965 +        rc = libxl_domain_rename(&ctx, domid,
  3.1966 +                                 migration_domname, common_domname, 0);
  3.1967 +        if (rc) goto perhaps_destroy_notify_rc;
  3.1968 +    }
  3.1969 +
  3.1970 +    rc = libxl_domain_unpause(&ctx, domid);
  3.1971 +    if (rc) goto perhaps_destroy_notify_rc;
  3.1972 +
  3.1973 +    fprintf(stderr, "migration target: Domain started successsfully.\n");
  3.1974 +    rc = 0;
  3.1975 +
  3.1976 + perhaps_destroy_notify_rc:
  3.1977 +    rc2 = libxl_write_exactly(&ctx, 1,
  3.1978 +                              migrate_report, sizeof(migrate_report),
  3.1979 +                              "migration ack stream",
  3.1980 +                              "success/failure report");
  3.1981 +    if (rc2) exit(-ERROR_BADFAIL);
  3.1982 +
  3.1983 +    rc_buf = -rc;
  3.1984 +    assert(!!rc_buf == !!rc);
  3.1985 +    rc2 = libxl_write_exactly(&ctx, 1, &rc_buf, 1,
  3.1986 +                              "migration ack stream",
  3.1987 +                              "success/failure code");
  3.1988 +    if (rc2) exit(-ERROR_BADFAIL);
  3.1989 +
  3.1990 +    if (rc) {
  3.1991 +        fprintf(stderr, "migration target: Failure, destroying our copy.\n");
  3.1992 +
  3.1993 +        rc2 = libxl_domain_destroy(&ctx, domid, 1);
  3.1994 +        if (rc2) {
  3.1995 +            fprintf(stderr, "migration target: Failed to destroy our copy"
  3.1996 +                    " (code %d).\n", rc2);
  3.1997 +            exit(-ERROR_BADFAIL);
  3.1998 +        }
  3.1999 +
  3.2000 +        fprintf(stderr, "migration target: Cleanup OK, granting sender"
  3.2001 +                " permission to resume.\n");
  3.2002 +
  3.2003 +        rc2 = libxl_write_exactly(&ctx, 1,
  3.2004 +                                  migrate_permission_to_go,
  3.2005 +                                  sizeof(migrate_permission_to_go),
  3.2006 +                                  "migration ack stream",
  3.2007 +                                  "permission to sender to have domain back");
  3.2008 +        if (rc2) exit(-ERROR_BADFAIL);
  3.2009 +    }
  3.2010 +
  3.2011 +    exit(0);
  3.2012 +}
  3.2013 +
  3.2014 +int main_restore(int argc, char **argv)
  3.2015 +{
  3.2016 +    char *checkpoint_file = NULL;
  3.2017 +    char *config_file = NULL;
  3.2018 +    int paused = 0, debug = 0, daemonize = 1;
  3.2019 +    int opt, rc;
  3.2020 +
  3.2021 +    while ((opt = getopt(argc, argv, "hpde")) != -1) {
  3.2022 +        switch (opt) {
  3.2023 +        case 'p':
  3.2024 +            paused = 1;
  3.2025 +            break;
  3.2026 +        case 'd':
  3.2027 +            debug = 1;
  3.2028 +            break;
  3.2029 +        case 'e':
  3.2030 +            daemonize = 0;
  3.2031 +            break;
  3.2032 +        case 'h':
  3.2033 +            help("restore");
  3.2034 +            exit(0);
  3.2035 +        default:
  3.2036 +            fprintf(stderr, "option not supported\n");
  3.2037 +            break;
  3.2038 +        }
  3.2039 +    }
  3.2040 +
  3.2041 +    if (argc-optind == 1) {
  3.2042 +        checkpoint_file = argv[optind];
  3.2043 +    } else if (argc-optind == 2) {
  3.2044 +        config_file = argv[optind];
  3.2045 +        checkpoint_file = argv[optind + 1];
  3.2046 +    } else {
  3.2047 +        help("restore");
  3.2048 +        exit(2);
  3.2049 +    }
  3.2050 +    rc = create_domain(debug, daemonize, config_file,
  3.2051 +                       checkpoint_file, paused, -1, 0);
  3.2052 +    exit(-rc);
  3.2053 +}
  3.2054 +
  3.2055 +int main_migrate_receive(int argc, char **argv)
  3.2056 +{
  3.2057 +    int debug = 0, daemonize = 1;
  3.2058 +    int opt;
  3.2059 +
  3.2060 +    while ((opt = getopt(argc, argv, "hed")) != -1) {
  3.2061 +        switch (opt) {
  3.2062 +        case 'h':
  3.2063 +            help("restore");
  3.2064 +            exit(2);
  3.2065 +            break;
  3.2066 +        case 'e':
  3.2067 +            daemonize = 0;
  3.2068 +            break;
  3.2069 +        case 'd':
  3.2070 +            debug = 1;
  3.2071 +            break;
  3.2072 +        default:
  3.2073 +            fprintf(stderr, "option not supported\n");
  3.2074 +            break;
  3.2075 +        }
  3.2076 +    }
  3.2077 +
  3.2078 +    if (argc-optind != 0) {
  3.2079 +        help("restore");
  3.2080 +        exit(2);
  3.2081 +    }
  3.2082 +    migrate_receive(debug, daemonize);
  3.2083 +    exit(0);
  3.2084 +}
  3.2085 +
  3.2086 +int main_save(int argc, char **argv)
  3.2087 +{
  3.2088 +    char *filename = NULL, *p = NULL;
  3.2089 +    const char *config_filename;
  3.2090 +    int checkpoint = 0;
  3.2091 +    int opt;
  3.2092 +
  3.2093 +    while ((opt = getopt(argc, argv, "hc")) != -1) {
  3.2094 +        switch (opt) {
  3.2095 +        case 'c':
  3.2096 +            checkpoint = 1;
  3.2097 +            break;
  3.2098 +        case 'h':
  3.2099 +            help("save");
  3.2100 +            exit(0);
  3.2101 +        default:
  3.2102 +            fprintf(stderr, "option not supported\n");
  3.2103 +            break;
  3.2104 +        }
  3.2105 +    }
  3.2106 +
  3.2107 +    if (argc-optind < 1 || argc-optind > 3) {
  3.2108 +        help("save");
  3.2109 +        exit(2);
  3.2110 +    }
  3.2111 +
  3.2112 +    p = argv[optind];
  3.2113 +    filename = argv[optind + 1];
  3.2114 +    config_filename = argv[optind + 2];
  3.2115 +    save_domain(p, filename, checkpoint, config_filename);
  3.2116 +    exit(0);
  3.2117 +}
  3.2118 +
  3.2119 +int main_migrate(int argc, char **argv)
  3.2120 +{
  3.2121 +    char *p = NULL;
  3.2122 +    const char *config_filename = NULL;
  3.2123 +    const char *ssh_command = "ssh";
  3.2124 +    char *rune = NULL;
  3.2125 +    char *host;
  3.2126 +    int opt, daemonize = 1, debug = 0;
  3.2127 +
  3.2128 +    while ((opt = getopt(argc, argv, "hC:s:ed")) != -1) {
  3.2129 +        switch (opt) {
  3.2130 +        case 'h':
  3.2131 +            help("migrate");
  3.2132 +            exit(0);
  3.2133 +        case 'C':
  3.2134 +            config_filename = optarg;
  3.2135 +            break;
  3.2136 +        case 's':
  3.2137 +            ssh_command = optarg;
  3.2138 +            break;
  3.2139 +        case 'e':
  3.2140 +            daemonize = 0;
  3.2141 +            break;
  3.2142 +        case 'd':
  3.2143 +            debug = 1;
  3.2144 +            break;
  3.2145 +        default:
  3.2146 +            fprintf(stderr, "option not supported\n");
  3.2147 +            break;
  3.2148 +        }
  3.2149 +    }
  3.2150 +
  3.2151 +    if (argc-optind < 2 || argc-optind > 2) {
  3.2152 +        help("save");
  3.2153 +        exit(2);
  3.2154 +    }
  3.2155 +
  3.2156 +    p = argv[optind];
  3.2157 +    host = argv[optind + 1];
  3.2158 +
  3.2159 +    if (!ssh_command[0]) {
  3.2160 +        rune= host;
  3.2161 +    } else {
  3.2162 +        asprintf(&rune, "exec %s %s xl migrate-receive%s%s",
  3.2163 +                 ssh_command, host,
  3.2164 +                 daemonize ? "" : " -e",
  3.2165 +                 debug ? " -d" : "");
  3.2166 +    }
  3.2167 +
  3.2168 +    migrate_domain(p, rune, config_filename);
  3.2169 +    exit(0);
  3.2170 +}
  3.2171 +
  3.2172 +int main_pause(int argc, char **argv)
  3.2173 +{
  3.2174 +    int opt;
  3.2175 +    char *p;
  3.2176 +    
  3.2177 +
  3.2178 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2179 +        switch (opt) {
  3.2180 +        case 'h':
  3.2181 +            help("pause");
  3.2182 +            exit(0);
  3.2183 +        default:
  3.2184 +            fprintf(stderr, "option not supported\n");
  3.2185 +            break;
  3.2186 +        }
  3.2187 +    }
  3.2188 +    if (optind >= argc) {
  3.2189 +        help("pause");
  3.2190 +        exit(2);
  3.2191 +    }
  3.2192 +
  3.2193 +    p = argv[optind];
  3.2194 +
  3.2195 +    pause_domain(p);
  3.2196 +    exit(0);
  3.2197 +}
  3.2198 +
  3.2199 +int main_unpause(int argc, char **argv)
  3.2200 +{
  3.2201 +    int opt;
  3.2202 +    char *p;
  3.2203 +    
  3.2204 +
  3.2205 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2206 +        switch (opt) {
  3.2207 +        case 'h':
  3.2208 +            help("unpause");
  3.2209 +            exit(0);
  3.2210 +        default:
  3.2211 +            fprintf(stderr, "option not supported\n");
  3.2212 +            break;
  3.2213 +        }
  3.2214 +    }
  3.2215 +    if (optind >= argc) {
  3.2216 +        help("unpause");
  3.2217 +        exit(2);
  3.2218 +    }
  3.2219 +
  3.2220 +    p = argv[optind];
  3.2221 +
  3.2222 +    unpause_domain(p);
  3.2223 +    exit(0);
  3.2224 +}
  3.2225 +
  3.2226 +int main_destroy(int argc, char **argv)
  3.2227 +{
  3.2228 +    int opt;
  3.2229 +    char *p;
  3.2230 +
  3.2231 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2232 +        switch (opt) {
  3.2233 +        case 'h':
  3.2234 +            help("destroy");
  3.2235 +            exit(0);
  3.2236 +        default:
  3.2237 +            fprintf(stderr, "option not supported\n");
  3.2238 +            break;
  3.2239 +        }
  3.2240 +    }
  3.2241 +    if (optind >= argc) {
  3.2242 +        help("destroy");
  3.2243 +        exit(2);
  3.2244 +    }
  3.2245 +
  3.2246 +    p = argv[optind];
  3.2247 +
  3.2248 +    destroy_domain(p);
  3.2249 +    exit(0);
  3.2250 +}
  3.2251 +
  3.2252 +int main_list(int argc, char **argv)
  3.2253 +{
  3.2254 +    int opt, verbose = 0;
  3.2255 +
  3.2256 +    while ((opt = getopt(argc, argv, "hv")) != -1) {
  3.2257 +        switch (opt) {
  3.2258 +        case 'h':
  3.2259 +            help("list");
  3.2260 +            exit(0);
  3.2261 +        case 'v':
  3.2262 +            verbose = 1;
  3.2263 +            break;
  3.2264 +        default:
  3.2265 +            fprintf(stderr, "option not supported\n");
  3.2266 +            break;
  3.2267 +        }
  3.2268 +    }
  3.2269 +
  3.2270 +    list_domains(verbose);
  3.2271 +    exit(0);
  3.2272 +}
  3.2273 +
  3.2274 +int main_list_vm(int argc, char **argv)
  3.2275 +{
  3.2276 +    int opt;
  3.2277 +
  3.2278 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2279 +        switch (opt) {
  3.2280 +        case 'h':
  3.2281 +            help("list-vm");
  3.2282 +            exit(0);
  3.2283 +        default:
  3.2284 +            fprintf(stderr, "option not supported\n");
  3.2285 +            break;
  3.2286 +        }
  3.2287 +    }
  3.2288 +
  3.2289 +    list_vm();
  3.2290 +    exit(0);
  3.2291 +}
  3.2292 +
  3.2293 +int main_create(int argc, char **argv)
  3.2294 +{
  3.2295 +    char *filename = NULL;
  3.2296 +    int paused = 0, debug = 0, daemonize = 1;
  3.2297 +    int opt, rc;
  3.2298 +
  3.2299 +    while ((opt = getopt(argc, argv, "hdep")) != -1) {
  3.2300 +        switch (opt) {
  3.2301 +        case 'p':
  3.2302 +            paused = 1;
  3.2303 +            break;
  3.2304 +        case 'd':
  3.2305 +            debug = 1;
  3.2306 +            break;
  3.2307 +        case 'e':
  3.2308 +            daemonize = 0;
  3.2309 +            break;
  3.2310 +        case 'h':
  3.2311 +            help("create");
  3.2312 +            exit(0);
  3.2313 +        default:
  3.2314 +            fprintf(stderr, "option not supported\n");
  3.2315 +            break;
  3.2316 +        }
  3.2317 +    }
  3.2318 +
  3.2319 +    if (optind >= argc) {
  3.2320 +        help("create");
  3.2321 +        exit(2);
  3.2322 +    }
  3.2323 +
  3.2324 +    filename = argv[optind];
  3.2325 +    rc = create_domain(debug, daemonize, filename, NULL, paused,
  3.2326 +                       -1, 0);
  3.2327 +    exit(-rc);
  3.2328 +}
  3.2329 +
  3.2330 +void button_press(char *p, char *b)
  3.2331 +{
  3.2332 +    libxl_button button;
  3.2333 +
  3.2334 +    find_domain(p);
  3.2335 +
  3.2336 +    if (!strcmp(b, "power")) {
  3.2337 +        button = POWER_BUTTON;
  3.2338 +    } else if (!strcmp(b, "sleep")) {
  3.2339 +        button = SLEEP_BUTTON;
  3.2340 +    } else {
  3.2341 +        fprintf(stderr, "%s is an invalid button identifier\n", b);
  3.2342 +        exit(2);
  3.2343 +    }
  3.2344 +
  3.2345 +    libxl_button_press(&ctx, domid, button);
  3.2346 +}
  3.2347 +
  3.2348 +int main_button_press(int argc, char **argv)
  3.2349 +{
  3.2350 +    int opt;
  3.2351 +    char *p;
  3.2352 +    char *b;
  3.2353 +
  3.2354 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2355 +        switch (opt) {
  3.2356 +        case 'h':
  3.2357 +            help("button-press");
  3.2358 +            exit(0);
  3.2359 +        default:
  3.2360 +            fprintf(stderr, "option not supported\n");
  3.2361 +            break;
  3.2362 +        }
  3.2363 +    }
  3.2364 +    if (optind >= argc - 1) {
  3.2365 +        help("button-press");
  3.2366 +        exit(2);
  3.2367 +    }
  3.2368 +
  3.2369 +    p = argv[optind];
  3.2370 +    b = argv[optind + 1];
  3.2371 +
  3.2372 +    button_press(p, b);
  3.2373 +    exit(0);
  3.2374 +}
  3.2375 +
  3.2376 +static void print_vcpuinfo(uint32_t tdomid,
  3.2377 +                           const struct libxl_vcpuinfo *vcpuinfo,
  3.2378 +                           uint32_t nr_cpus)
  3.2379 +{
  3.2380 +    int i, l;
  3.2381 +    uint64_t *cpumap;
  3.2382 +    uint64_t pcpumap;
  3.2383 +
  3.2384 +    /*      NAME  ID  VCPU */
  3.2385 +    printf("%-32s %5u %5u",
  3.2386 +           libxl_domid_to_name(&ctx, tdomid), tdomid, vcpuinfo->vcpuid);
  3.2387 +    if (!vcpuinfo->online) {
  3.2388 +        /*      CPU STA */
  3.2389 +        printf("%5c %3c%cp ", '-', '-', '-');
  3.2390 +    } else {
  3.2391 +        /*      CPU STA */
  3.2392 +        printf("%5u %3c%c- ", vcpuinfo->cpu,
  3.2393 +               vcpuinfo->running ? 'r' : '-',
  3.2394 +               vcpuinfo->blocked ? 'b' : '-');
  3.2395 +    }
  3.2396 +    /*      TIM */
  3.2397 +    printf("%9.1f  ", ((float)vcpuinfo->vcpu_time / 1e9));
  3.2398 +    /* CPU AFFINITY */
  3.2399 +    pcpumap = nr_cpus > 64 ? -1 : ((1 << nr_cpus) - 1);
  3.2400 +    for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
  3.2401 +        if (*cpumap < pcpumap) {
  3.2402 +            break;
  3.2403 +        }
  3.2404 +        if (nr_cpus > 64) {
  3.2405 +            pcpumap = -1;
  3.2406 +            nr_cpus -= 64;
  3.2407 +        } else {
  3.2408 +            pcpumap = ((1 << nr_cpus) - 1);
  3.2409 +            nr_cpus = 0;
  3.2410 +        }
  3.2411 +    }
  3.2412 +    if (!nr_cpus) {
  3.2413 +        printf("any cpu\n");
  3.2414 +    } else {
  3.2415 +        for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
  3.2416 +            pcpumap = *cpumap;
  3.2417 +            for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1)
  3.2418 +                ;
  3.2419 +            printf("%u", i);
  3.2420 +            for (l = i, pcpumap = (pcpumap >> 1); (pcpumap & 1); ++i, pcpumap >>= 1)
  3.2421 +                ;
  3.2422 +            if (l < i) {
  3.2423 +                printf("-%u", i);
  3.2424 +            }
  3.2425 +            for (++i; pcpumap; ++i, pcpumap >>= 1) {
  3.2426 +                if (pcpumap & 1) {
  3.2427 +                    printf(",%u", i);
  3.2428 +                    for (l = i, pcpumap = (pcpumap >> 1); (pcpumap & 1); ++i, pcpumap >>= 1)
  3.2429 +                        ;
  3.2430 +                    if (l < i) {
  3.2431 +                        printf("-%u", i);
  3.2432 +                    }
  3.2433 +                    ++i;
  3.2434 +                }
  3.2435 +            }
  3.2436 +            printf("\n");
  3.2437 +            nr_cpus = nr_cpus > 64 ? nr_cpus - 64 : 0;
  3.2438 +        }
  3.2439 +    }
  3.2440 +}
  3.2441 +
  3.2442 +void vcpulist(int argc, char **argv)
  3.2443 +{
  3.2444 +    struct libxl_dominfo *dominfo;
  3.2445 +    struct libxl_vcpuinfo *vcpuinfo;
  3.2446 +    struct libxl_physinfo physinfo;
  3.2447 +    int nb_vcpu, nb_domain, cpusize;
  3.2448 +
  3.2449 +    if (libxl_get_physinfo(&ctx, &physinfo) != 0) {
  3.2450 +        fprintf(stderr, "libxl_physinfo failed.\n");
  3.2451 +        goto vcpulist_out;
  3.2452 +    }
  3.2453 +    printf("%-32s %5s %5s %5s %5s %9s %s\n",
  3.2454 +           "Name", "ID", "VCPU", "CPU", "State", "Time(s)", "CPU Affinity");
  3.2455 +    if (!argc) {
  3.2456 +        if (!(dominfo = libxl_list_domain(&ctx, &nb_domain))) {
  3.2457 +            fprintf(stderr, "libxl_list_domain failed.\n");
  3.2458 +            goto vcpulist_out;
  3.2459 +        }
  3.2460 +        for (; nb_domain > 0; --nb_domain, ++dominfo) {
  3.2461 +            if (!(vcpuinfo = libxl_list_vcpu(&ctx, dominfo->domid, &nb_vcpu, &cpusize))) {
  3.2462 +                fprintf(stderr, "libxl_list_vcpu failed.\n");
  3.2463 +                goto vcpulist_out;
  3.2464 +            }
  3.2465 +            for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  3.2466 +                print_vcpuinfo(dominfo->domid, vcpuinfo, physinfo.nr_cpus);
  3.2467 +            }
  3.2468 +        }
  3.2469 +    } else {
  3.2470 +        for (; argc > 0; ++argv, --argc) {
  3.2471 +            if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) {
  3.2472 +                fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
  3.2473 +            }
  3.2474 +            if (!(vcpuinfo = libxl_list_vcpu(&ctx, domid, &nb_vcpu, &cpusize))) {
  3.2475 +                fprintf(stderr, "libxl_list_vcpu failed.\n");
  3.2476 +                goto vcpulist_out;
  3.2477 +            }
  3.2478 +            for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  3.2479 +                print_vcpuinfo(domid, vcpuinfo, physinfo.nr_cpus);
  3.2480 +            }
  3.2481 +        }
  3.2482 +    }
  3.2483 +  vcpulist_out:
  3.2484 +    ;
  3.2485 +}
  3.2486 +
  3.2487 +void main_vcpulist(int argc, char **argv)
  3.2488 +{
  3.2489 +    int opt;
  3.2490 +
  3.2491 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2492 +        switch (opt) {
  3.2493 +        case 'h':
  3.2494 +            help("vcpu-list");
  3.2495 +            exit(0);
  3.2496 +        default:
  3.2497 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  3.2498 +            break;
  3.2499 +        }
  3.2500 +    }
  3.2501 +
  3.2502 +    vcpulist(argc - 1, argv + 1);
  3.2503 +    exit(0);
  3.2504 +}
  3.2505 +
  3.2506 +void vcpupin(char *d, const char *vcpu, char *cpu)
  3.2507 +{
  3.2508 +    struct libxl_vcpuinfo *vcpuinfo;
  3.2509 +    struct libxl_physinfo physinfo;
  3.2510 +    uint64_t *cpumap = NULL;
  3.2511 +
  3.2512 +    uint32_t vcpuid, cpuida, cpuidb;
  3.2513 +    char *endptr, *toka, *tokb;
  3.2514 +    int i, nb_vcpu, cpusize;
  3.2515 +
  3.2516 +    vcpuid = strtoul(vcpu, &endptr, 10);
  3.2517 +    if (vcpu == endptr) {
  3.2518 +        if (strcmp(vcpu, "all")) {
  3.2519 +            fprintf(stderr, "Error: Invalid argument.\n");
  3.2520 +            return;
  3.2521 +        }
  3.2522 +        vcpuid = -1;
  3.2523 +    }
  3.2524 +
  3.2525 +    find_domain(d);
  3.2526 +
  3.2527 +    if (libxl_get_physinfo(&ctx, &physinfo) != 0) {
  3.2528 +        fprintf(stderr, "libxl_get_physinfo failed.\n");
  3.2529 +        goto vcpupin_out1;
  3.2530 +    }
  3.2531 +
  3.2532 +    cpumap = calloc(physinfo.max_cpu_id + 1, sizeof (uint64_t));
  3.2533 +    if (!cpumap) {
  3.2534 +        goto vcpupin_out1;
  3.2535 +    }
  3.2536 +    if (strcmp(cpu, "all")) {
  3.2537 +        for (toka = strtok(cpu, ","), i = 0; toka; toka = strtok(NULL, ","), ++i) {
  3.2538 +            cpuida = strtoul(toka, &endptr, 10);
  3.2539 +            if (toka == endptr) {
  3.2540 +                fprintf(stderr, "Error: Invalid argument.\n");
  3.2541 +                goto vcpupin_out;
  3.2542 +            }
  3.2543 +            if (*endptr == '-') {
  3.2544 +                tokb = endptr + 1;
  3.2545 +                cpuidb = strtoul(tokb, &endptr, 10);
  3.2546 +                if ((tokb == endptr) || (cpuida > cpuidb)) {
  3.2547 +                    fprintf(stderr, "Error: Invalid argument.\n");
  3.2548 +                    goto vcpupin_out;
  3.2549 +                }
  3.2550 +                while (cpuida <= cpuidb) {
  3.2551 +                    cpumap[cpuida / 64] |= (1 << (cpuida % 64));
  3.2552 +                    ++cpuida;
  3.2553 +                }
  3.2554 +            } else {
  3.2555 +                cpumap[cpuida / 64] |= (1 << (cpuida % 64));
  3.2556 +            }
  3.2557 +        }
  3.2558 +    }
  3.2559 +    else {
  3.2560 +        memset(cpumap, -1, sizeof (uint64_t) * (physinfo.max_cpu_id + 1));
  3.2561 +    }
  3.2562 +
  3.2563 +    if (vcpuid != -1) {
  3.2564 +        if (libxl_set_vcpuaffinity(&ctx, domid, vcpuid,
  3.2565 +                                   cpumap, physinfo.max_cpu_id + 1) == -1) {
  3.2566 +            fprintf(stderr, "Could not set affinity for vcpu `%u'.\n", vcpuid);
  3.2567 +        }
  3.2568 +    }
  3.2569 +    else {
  3.2570 +        if (!(vcpuinfo = libxl_list_vcpu(&ctx, domid, &nb_vcpu, &cpusize))) {
  3.2571 +            fprintf(stderr, "libxl_list_vcpu failed.\n");
  3.2572 +            goto vcpupin_out;
  3.2573 +        }
  3.2574 +        for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
  3.2575 +            if (libxl_set_vcpuaffinity(&ctx, domid, vcpuinfo->vcpuid,
  3.2576 +                                       cpumap, physinfo.max_cpu_id + 1) == -1) {
  3.2577 +                fprintf(stderr, "libxl_list_vcpu failed on vcpu `%u'.\n", vcpuinfo->vcpuid);
  3.2578 +            }
  3.2579 +        }
  3.2580 +    }
  3.2581 +  vcpupin_out1:
  3.2582 +    free(cpumap);
  3.2583 +  vcpupin_out:
  3.2584 +    ;
  3.2585 +}
  3.2586 +
  3.2587 +int main_vcpupin(int argc, char **argv)
  3.2588 +{
  3.2589 +    int opt;
  3.2590 +
  3.2591 +    if (argc != 4) {
  3.2592 +        help("vcpu-pin");
  3.2593 +        exit(0);
  3.2594 +    }
  3.2595 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2596 +        switch (opt) {
  3.2597 +        case 'h':
  3.2598 +            help("vcpu-pin");
  3.2599 +            exit(0);
  3.2600 +        default:
  3.2601 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  3.2602 +            break;
  3.2603 +        }
  3.2604 +    }
  3.2605 +
  3.2606 +    vcpupin(argv[1], argv[2] , argv[3]);
  3.2607 +    exit(0);
  3.2608 +}
  3.2609 +
  3.2610 +void vcpuset(char *d, char* nr_vcpus)
  3.2611 +{
  3.2612 +    char *endptr;
  3.2613 +    unsigned int max_vcpus;
  3.2614 +
  3.2615 +    max_vcpus = strtoul(nr_vcpus, &endptr, 10);
  3.2616 +    if (nr_vcpus == endptr) {
  3.2617 +        fprintf(stderr, "Error: Invalid argument.\n");
  3.2618 +        return;
  3.2619 +    }
  3.2620 +
  3.2621 +    find_domain(d);
  3.2622 +
  3.2623 +    if (libxl_set_vcpucount(&ctx, domid, max_vcpus) == ERROR_INVAL) {
  3.2624 +        fprintf(stderr, "Error: Cannot set vcpus greater than max vcpus on running domain or lesser than 1.\n");
  3.2625 +    }
  3.2626 +}
  3.2627 +
  3.2628 +int main_vcpuset(int argc, char **argv)
  3.2629 +{
  3.2630 +    int opt;
  3.2631 +
  3.2632 +    if (argc != 3) {
  3.2633 +        help("vcpu-set");
  3.2634 +        exit(0);
  3.2635 +    }
  3.2636 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2637 +        switch (opt) {
  3.2638 +        case 'h':
  3.2639 +        help("vcpu-set");
  3.2640 +            exit(0);
  3.2641 +        default:
  3.2642 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  3.2643 +            break;
  3.2644 +        }
  3.2645 +    }
  3.2646 +
  3.2647 +    vcpuset(argv[1], argv[2]);
  3.2648 +    exit(0);
  3.2649 +}
  3.2650 +
  3.2651 +static void output_xeninfo(void)
  3.2652 +{
  3.2653 +    const libxl_version_info *info;
  3.2654 +    int sched_id;
  3.2655 +
  3.2656 +    info = libxl_get_version_info(&ctx);
  3.2657 +    if ((sched_id = libxl_get_sched_id(&ctx)) < 0) {
  3.2658 +        fprintf(stderr, "get_sched_id sysctl failed.\n");
  3.2659 +        return;
  3.2660 +    }
  3.2661 +
  3.2662 +    printf("xen_major              : %d\n", info->xen_version_major);
  3.2663 +    printf("xen_minor              : %d\n", info->xen_version_minor);
  3.2664 +    printf("xen_extra              : %s\n", info->xen_version_extra);
  3.2665 +    printf("xen_caps               : %s\n", info->capabilities);
  3.2666 +    printf("xen_scheduler          : %s\n",
  3.2667 +        sched_id == XEN_SCHEDULER_SEDF ? "sedf" :
  3.2668 +        sched_id == XEN_SCHEDULER_CREDIT ? "credit" :
  3.2669 +        sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown");
  3.2670 +    printf("xen_pagesize           : %lu\n", info->pagesize);
  3.2671 +    printf("platform_params        : virt_start=0x%lx\n", info->virt_start);
  3.2672 +    printf("xen_changeset          : %s\n", info->changeset);
  3.2673 +    printf("xen_commandline        : %s\n", info->commandline);
  3.2674 +    printf("cc_compiler            : %s\n", info->compiler);
  3.2675 +    printf("cc_compile_by          : %s\n", info->compile_by);
  3.2676 +    printf("cc_compile_domain      : %s\n", info->compile_domain);
  3.2677 +    printf("cc_compile_date        : %s\n", info->compile_date);
  3.2678 +
  3.2679 +    return;
  3.2680 +}
  3.2681 +
  3.2682 +static void output_nodeinfo(void)
  3.2683 +{
  3.2684 +    struct utsname utsbuf;
  3.2685 +
  3.2686 +    uname(&utsbuf);
  3.2687 +
  3.2688 +    printf("host                   : %s\n", utsbuf.nodename);
  3.2689 +    printf("release                : %s\n", utsbuf.release);
  3.2690 +    printf("version                : %s\n", utsbuf.version);
  3.2691 +    printf("machine                : %s\n", utsbuf.machine);
  3.2692 +
  3.2693 +    return;
  3.2694 +}
  3.2695 +
  3.2696 +static void output_physinfo(void)
  3.2697 +{
  3.2698 +    struct libxl_physinfo info;
  3.2699 +    const libxl_version_info *vinfo;
  3.2700 +    unsigned int i;
  3.2701 +
  3.2702 +    if (libxl_get_physinfo(&ctx, &info) != 0) {
  3.2703 +        fprintf(stderr, "libxl_physinfo failed.\n");
  3.2704 +        return;
  3.2705 +    }
  3.2706 +
  3.2707 +    printf("nr_cpus                : %d\n", info.nr_cpus);
  3.2708 +    printf("nr_nodes               : %d\n", info.nr_nodes);
  3.2709 +    printf("cores_per_socket       : %d\n", info.cores_per_socket);
  3.2710 +    printf("threads_per_core       : %d\n", info.threads_per_core);
  3.2711 +    printf("cpu_mhz                : %d\n", info.cpu_khz / 1000);
  3.2712 +    printf("hw_caps                : ");
  3.2713 +    for (i = 0; i < 8; i++)
  3.2714 +        printf("%08x%c", info.hw_cap[i], i < 7 ? ':' : '\n');
  3.2715 +    printf("virt_caps              :");
  3.2716 +    if (info.phys_cap & XEN_SYSCTL_PHYSCAP_hvm)
  3.2717 +        printf(" hvm");
  3.2718 +    if (info.phys_cap & XEN_SYSCTL_PHYSCAP_hvm_directio)
  3.2719 +        printf(" hvm_directio");
  3.2720 +    printf("\n");
  3.2721 +    vinfo = libxl_get_version_info(&ctx);
  3.2722 +    i = (1 << 20) / vinfo->pagesize;
  3.2723 +    printf("total_memory           : %lu\n", info.total_pages / i);
  3.2724 +    printf("free_memory            : %lu\n", info.free_pages / i);
  3.2725 +
  3.2726 +    return;
  3.2727 +}
  3.2728 +
  3.2729 +static void info(int verbose)
  3.2730 +{
  3.2731 +    output_nodeinfo();
  3.2732 +
  3.2733 +    output_physinfo();
  3.2734 +
  3.2735 +    output_xeninfo();
  3.2736 +
  3.2737 +    printf("xend_config_format     : 4\n");
  3.2738 +
  3.2739 +    return;
  3.2740 +}
  3.2741 +
  3.2742 +void main_info(int argc, char **argv)
  3.2743 +{
  3.2744 +    int opt, verbose;
  3.2745 +
  3.2746 +    verbose = 0;
  3.2747 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  3.2748 +        switch (opt) {
  3.2749 +        case 'h':
  3.2750 +            help("vcpu-list");
  3.2751 +            exit(0);
  3.2752 +        default:
  3.2753 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  3.2754 +            break;
  3.2755 +        }
  3.2756 +    }
  3.2757 +
  3.2758 +    info(verbose);
  3.2759 +    exit(0);
  3.2760 +}
  3.2761 +
  3.2762 +static int sched_credit_domain_get(
  3.2763 +    int domid, struct libxl_sched_credit *scinfo)
  3.2764 +{
  3.2765 +    int rc;
  3.2766 +
  3.2767 +    rc = libxl_sched_credit_domain_get(&ctx, domid, scinfo);
  3.2768 +    if (rc)
  3.2769 +        fprintf(stderr, "libxl_sched_credit_domain_get failed.\n");
  3.2770 +    
  3.2771 +    return rc;
  3.2772 +}
  3.2773 +
  3.2774 +static int sched_credit_domain_set(
  3.2775 +    int domid, struct libxl_sched_credit *scinfo)
  3.2776 +{
  3.2777 +    int rc;
  3.2778 +
  3.2779 +    rc = libxl_sched_credit_domain_set(&ctx, domid, scinfo);
  3.2780 +    if (rc)
  3.2781 +        fprintf(stderr, "libxl_sched_credit_domain_set failed.\n");
  3.2782 +
  3.2783 +    return rc;
  3.2784 +}
  3.2785 +
  3.2786 +static void sched_credit_domain_output(
  3.2787 +    int domid, struct libxl_sched_credit *scinfo)
  3.2788 +{
  3.2789 +    printf("%-33s %4d %6d %4d\n",
  3.2790 +        libxl_domid_to_name(&ctx, domid),
  3.2791 +        domid,
  3.2792 +        scinfo->weight,
  3.2793 +        scinfo->cap);
  3.2794 +}
  3.2795 +
  3.2796 +void main_sched_credit(int argc, char **argv)
  3.2797 +{
  3.2798 +    struct libxl_dominfo *info;
  3.2799 +    struct libxl_sched_credit scinfo;
  3.2800 +    int nb_domain, i;
  3.2801 +    char *dom = NULL;
  3.2802 +    int weight = 256, cap = 0, opt_w = 0, opt_c = 0;
  3.2803 +    int opt, rc;
  3.2804 +
  3.2805 +    while ((opt = getopt(argc, argv, "hd:w:c:")) != -1) {
  3.2806 +        switch (opt) {
  3.2807 +        case 'd':
  3.2808 +            dom = optarg;
  3.2809 +            break;
  3.2810 +        case 'w':
  3.2811 +            weight = strtol(optarg, NULL, 10);
  3.2812 +            opt_w = 1;
  3.2813 +            break;
  3.2814 +        case 'c':
  3.2815 +            cap = strtol(optarg, NULL, 10);
  3.2816 +            opt_c = 1;
  3.2817 +            break;
  3.2818 +        case 'h':
  3.2819 +            help("sched-credit");
  3.2820 +            exit(0);
  3.2821 +        default:
  3.2822 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  3.2823 +            break;
  3.2824 +        }
  3.2825 +    }
  3.2826 +
  3.2827 +    if (!dom && (opt_w || opt_c)) {
  3.2828 +        fprintf(stderr, "Must specify a domain.\n");
  3.2829 +        exit(1);
  3.2830 +    }
  3.2831 +
  3.2832 +    if (!dom) { /* list all domain's credit scheduler info */
  3.2833 +        info = libxl_list_domain(&ctx, &nb_domain);
  3.2834 +        if (!info) {
  3.2835 +            fprintf(stderr, "libxl_domain_infolist failed.\n");
  3.2836 +            exit(1);
  3.2837 +        }
  3.2838 +
  3.2839 +        printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
  3.2840 +        for (i = 0; i < nb_domain; i++) {
  3.2841 +            rc = sched_credit_domain_get(info[i].domid, &scinfo);
  3.2842 +            if (rc)
  3.2843 +                exit(-rc);
  3.2844 +            sched_credit_domain_output(info[i].domid, &scinfo);
  3.2845 +        }
  3.2846 +    } else {
  3.2847 +        find_domain(dom);
  3.2848 +
  3.2849 +        rc = sched_credit_domain_get(domid, &scinfo);
  3.2850 +        if (rc)
  3.2851 +            exit(-rc);
  3.2852 +
  3.2853 +        if (!opt_w && !opt_c) { /* output credit scheduler info */
  3.2854 +            printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
  3.2855 +            sched_credit_domain_output(domid, &scinfo);
  3.2856 +        } else { /* set credit scheduler paramaters */
  3.2857 +            if (opt_w)
  3.2858 +                scinfo.weight = weight;
  3.2859 +            if (opt_c)
  3.2860 +                scinfo.cap = cap;
  3.2861 +            rc = sched_credit_domain_set(domid, &scinfo);
  3.2862 +            if (rc)
  3.2863 +                exit(-rc);
  3.2864 +        }
  3.2865 +    }
  3.2866 +
  3.2867 +    exit(0);
  3.2868 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxl/xl_cmdimpl.h	Tue May 04 11:23:17 2010 +0100
     4.3 @@ -0,0 +1,39 @@
     4.4 +/*
     4.5 + * Author Yang Hongyang <yanghy@cn.fujitsu.com>
     4.6 + *
     4.7 + * This program is free software; you can redistribute it and/or modify
     4.8 + * it under the terms of the GNU Lesser General Public License as published
     4.9 + * by the Free Software Foundation; version 2.1 only. with the special
    4.10 + * exception on linking described in file LICENSE.
    4.11 + *
    4.12 + * This program is distributed in the hope that it will be useful,
    4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.15 + * GNU Lesser General Public License for more details.
    4.16 + */
    4.17 +
    4.18 +int main_vcpulist(int argc, char **argv);
    4.19 +int main_info(int argc, char **argv);
    4.20 +int main_cd_eject(int argc, char **argv);
    4.21 +int main_cd_insert(int argc, char **argv);
    4.22 +int main_console(int argc, char **argv);
    4.23 +int main_pcilist(int argc, char **argv);
    4.24 +int main_pcidetach(int argc, char **argv);
    4.25 +int main_pciattach(int argc, char **argv);
    4.26 +int main_restore(int argc, char **argv);
    4.27 +int main_migrate_receive(int argc, char **argv);
    4.28 +int main_save(int argc, char **argv);
    4.29 +int main_migrate(int argc, char **argv);
    4.30 +int main_pause(int argc, char **argv);
    4.31 +int main_unpause(int argc, char **argv);
    4.32 +int main_destroy(int argc, char **argv);
    4.33 +int main_list(int argc, char **argv);
    4.34 +int main_list_vm(int argc, char **argv);
    4.35 +int main_create(int argc, char **argv);
    4.36 +int main_button_press(int argc, char **argv);
    4.37 +int main_vcpupin(int argc, char **argv);
    4.38 +int main_vcpuset(int argc, char **argv);
    4.39 +int main_memset(int argc, char **argv);
    4.40 +void main_sched_credit(int argc, char **argv);
    4.41 +
    4.42 +void help(char *command);