debuggers.hg
changeset 21293:742311878ae5
xl: Move xl command implementation to a seperate file
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
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);