From: Peter Dinda Date: Mon, 18 Mar 2013 19:05:08 +0000 (-0500) Subject: Checkpointing and migration now support options, the first of which are: skipping... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=6b055801f5e04e134b779ad49bc4826179ebf6bb;p=palacios.releases.git Checkpointing and migration now support options, the first of which are: skipping memory, skipping devices, skipping cores, and skipping the archtecture-dependent state --- diff --git a/linux_module/palacios.h b/linux_module/palacios.h index 99ef5ef..8810f44 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -70,6 +70,12 @@ struct v3_core_move_cmd { struct v3_chkpt_info { char store[128]; char url[256]; /* This might need to be bigger... */ + unsigned long long opts; +#define V3_CHKPT_OPT_NONE 0 +#define V3_CHKPT_OPT_SKIP_MEM 1 // don't write memory to store +#define V3_CHKPT_OPT_SKIP_DEVS 2 // don't write devices to store +#define V3_CHKPT_OPT_SKIP_CORES 4 // don't write core arch ind data to store +#define V3_CHKPT_OPT_SKIP_ARCHDEP 8 // don't write core arch dep data to store } __attribute__((packed)); diff --git a/linux_module/vm.c b/linux_module/vm.c index 54d5efd..b7425e4 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -212,7 +212,7 @@ static long v3_vm_ioctl(struct file * filp, NOTICE("Saving Guest to %s:%s\n", chkpt.store, chkpt.url); - if (v3_save_vm(guest->v3_ctx, chkpt.store, chkpt.url) == -1) { + if (v3_save_vm(guest->v3_ctx, chkpt.store, chkpt.url, chkpt.opts) == -1) { WARNING("Error checkpointing VM state\n"); return -EFAULT; } @@ -232,7 +232,7 @@ static long v3_vm_ioctl(struct file * filp, NOTICE("Loading Guest from %s:%s\n", chkpt.store, chkpt.url); - if (v3_load_vm(guest->v3_ctx, chkpt.store, chkpt.url) == -1) { + if (v3_load_vm(guest->v3_ctx, chkpt.store, chkpt.url, chkpt.opts) == -1) { WARNING("Error Loading VM state\n"); return -EFAULT; } @@ -256,7 +256,7 @@ static long v3_vm_ioctl(struct file * filp, NOTICE("Sending (live-migrating) Guest to %s:%s\n",chkpt_info.store, chkpt_info.url); - if (v3_send_vm(guest->v3_ctx, chkpt_info.store, chkpt_info.url) == -1) { + if (v3_send_vm(guest->v3_ctx, chkpt_info.store, chkpt_info.url, chkpt_info.opts) == -1) { WARNING("Error sending VM\n"); return -EFAULT; } @@ -278,7 +278,7 @@ static long v3_vm_ioctl(struct file * filp, NOTICE("Receiving (live-migrating) Guest to %s:%s\n",chkpt_info.store, chkpt_info.url); - if (v3_receive_vm(guest->v3_ctx, chkpt_info.store, chkpt_info.url) == -1) { + if (v3_receive_vm(guest->v3_ctx, chkpt_info.store, chkpt_info.url, chkpt_info.opts) == -1) { WARNING("Error receiving VM\n"); return -EFAULT; } diff --git a/linux_usr/v3_ctrl.h b/linux_usr/v3_ctrl.h index e81968c..929d7e6 100644 --- a/linux_usr/v3_ctrl.h +++ b/linux_usr/v3_ctrl.h @@ -77,6 +77,12 @@ struct v3_debug_cmd { struct v3_chkpt_info { char store[128]; char url[256]; /* This might need to be bigger... */ + unsigned long long opts; +#define V3_CHKPT_OPT_NONE 0 +#define V3_CHKPT_OPT_SKIP_MEM 1 // don't write memory to store +#define V3_CHKPT_OPT_SKIP_DEVS 2 // don't write devices to store +#define V3_CHKPT_OPT_SKIP_CORES 4 // don't write core arch ind data to store +#define V3_CHKPT_OPT_SKIP_ARCHDEP 8 // don't write core arch dep data to store } __attribute__((packed)); diff --git a/linux_usr/v3_load.c b/linux_usr/v3_load.c index a409a2d..7e3e212 100644 --- a/linux_usr/v3_load.c +++ b/linux_usr/v3_load.c @@ -32,7 +32,13 @@ int main(int argc, char* argv[]) { char * vm_dev = NULL; if (argc < 4) { - printf("usage: v3_load \n"); + printf("usage: v3_load [optionmask]\n"); + printf(" optionmask consists of the sum of any of the following\n"); + printf(" 0 none\n"); + printf(" 1 skip memory\n"); + printf(" 2 skip devices\n"); + printf(" 4 skip cores\n"); + printf(" 8 skip architecture-specific core state\n"); return -1; } @@ -53,6 +59,12 @@ int main(int argc, char* argv[]) { strncpy(chkpt.url, argv[3], MAX_URL_LEN); + if (argc>4) { + chkpt.opts = atoll(argv[4]); + } else { + chkpt.opts = V3_CHKPT_OPT_NONE; + } + vm_fd = open(vm_dev, O_RDONLY); if (vm_fd == -1) { printf("Error opening VM device: %s\n", vm_dev); diff --git a/linux_usr/v3_receive.c b/linux_usr/v3_receive.c index 9c3fafd..153ccd9 100644 --- a/linux_usr/v3_receive.c +++ b/linux_usr/v3_receive.c @@ -32,7 +32,13 @@ int main(int argc, char* argv[]) { char * vm_dev = NULL; if (argc < 4) { - printf("Usage: ./v3_receive \n"); + printf("Usage: ./v3_receive [optionmask]\n"); + printf(" optionmask consists of the sum of any of the following\n"); + printf(" 0 none\n"); + printf(" 1 skip memory\n"); + printf(" 2 skip devices\n"); + printf(" 4 skip cores\n"); + printf(" 8 skip architecture-specific core state\n"); return -1; } @@ -53,6 +59,12 @@ int main(int argc, char* argv[]) { strncpy(chkpt.url, argv[3], MAX_URL_LEN); + if (argc>4) { + chkpt.opts = atoll(argv[4]); + } else { + chkpt.opts = V3_CHKPT_OPT_NONE; + } + vm_fd = open(vm_dev, O_RDONLY); if (vm_fd == -1) { printf("Error opening VM device: %s\n", vm_dev); diff --git a/linux_usr/v3_save.c b/linux_usr/v3_save.c index 46ae513..4749c5a 100644 --- a/linux_usr/v3_save.c +++ b/linux_usr/v3_save.c @@ -31,8 +31,16 @@ int main(int argc, char* argv[]) { int vm_fd; char * vm_dev = NULL; + + if (argc < 4) { - printf("usage: v3_save \n"); + printf("usage: v3_save [optionmask]\n"); + printf(" optionmask consists of the sum of any of the following\n"); + printf(" 0 none\n"); + printf(" 1 skip memory\n"); + printf(" 2 skip devices\n"); + printf(" 4 skip cores\n"); + printf(" 8 skip architecture-specific core state\n"); return -1; } @@ -45,7 +53,6 @@ int main(int argc, char* argv[]) { strncpy(chkpt.store, argv[2], MAX_STORE_LEN); - if (strlen(argv[3]) >= MAX_URL_LEN) { printf("ERROR: Checkpoint URL longer than maximum size (%d)\n", MAX_URL_LEN); return -1; @@ -53,6 +60,13 @@ int main(int argc, char* argv[]) { strncpy(chkpt.url, argv[3], MAX_URL_LEN); + if (argc>4) { + chkpt.opts = atoll(argv[4]); + } else { + chkpt.opts = V3_CHKPT_OPT_NONE; + } + + vm_fd = open(vm_dev, O_RDONLY); if (vm_fd == -1) { printf("Error opening VM device: %s\n", vm_dev); diff --git a/linux_usr/v3_send.c b/linux_usr/v3_send.c index fcb71c4..523be30 100644 --- a/linux_usr/v3_send.c +++ b/linux_usr/v3_send.c @@ -32,7 +32,13 @@ int main(int argc, char* argv[]) { char * vm_dev = NULL; if (argc < 4) { - printf("Usage: ./v3_send \n"); + printf("Usage: ./v3_send [optionmask]\n"); + printf(" optionmask consists of the sum of any of the following\n"); + printf(" 0 none\n"); + printf(" 1 skip memory\n"); + printf(" 2 skip devices\n"); + printf(" 4 skip cores\n"); + printf(" 8 skip architecture-specific core state\n"); return -1; } @@ -53,6 +59,12 @@ int main(int argc, char* argv[]) { strncpy(chkpt.url, argv[3], MAX_URL_LEN); + if (argc>4) { + chkpt.opts = atoll(argv[4]); + } else { + chkpt.opts = V3_CHKPT_OPT_NONE; + } + vm_fd = open(vm_dev, O_RDONLY); if (vm_fd == -1) { printf("Error opening VM device: %s\n", vm_dev); diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 083644e..5379928 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -386,11 +386,11 @@ int v3_pause_vm(struct v3_vm_info * vm); int v3_continue_vm(struct v3_vm_info * vm); int v3_simulate_vm(struct v3_vm_info * vm, unsigned int msecs); -int v3_save_vm(struct v3_vm_info * vm, char * store, char * url); -int v3_load_vm(struct v3_vm_info * vm, char * store, char * url); +int v3_save_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts); +int v3_load_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts); -int v3_send_vm(struct v3_vm_info * vm, char * store, char * url); -int v3_receive_vm(struct v3_vm_info * vm, char * store, char * url); +int v3_send_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts); +int v3_receive_vm(struct v3_vm_info * vm, char * store, char * url, unsigned long long opts); int v3_move_vm_core(struct v3_vm_info * vm, int vcore_id, int target_cpu); diff --git a/palacios/include/palacios/vmm_checkpoint.h b/palacios/include/palacios/vmm_checkpoint.h index 3b1a06e..8bd5f5a 100644 --- a/palacios/include/palacios/vmm_checkpoint.h +++ b/palacios/include/palacios/vmm_checkpoint.h @@ -156,12 +156,21 @@ int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, char * name); int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx); -int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url); -int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url); + +typedef uint64_t v3_chkpt_options_t; +// The options are a bitwise or of the following +#define V3_CHKPT_OPT_NONE 0 +#define V3_CHKPT_OPT_SKIP_MEM 1 // don't write memory to store +#define V3_CHKPT_OPT_SKIP_DEVS 2 // don't write devices to store +#define V3_CHKPT_OPT_SKIP_CORES 4 // don't write core arch ind data to store +#define V3_CHKPT_OPT_SKIP_ARCHDEP 8 // don't write core arch dep data to store + +int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts); +int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts); #ifdef V3_CONFIG_LIVE_MIGRATION -int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url); -int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url); +int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts); +int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts); #endif int V3_init_checkpoint(); diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 6e32e88..61aa245 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -720,23 +720,23 @@ int v3_get_state_vm(struct v3_vm_info *vm, struct v3_vm_state *s) #ifdef V3_CONFIG_CHECKPOINT #include -int v3_save_vm(struct v3_vm_info * vm, char * store, char * url) { - return v3_chkpt_save_vm(vm, store, url); +int v3_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { + return v3_chkpt_save_vm(vm, store, url, opts); } -int v3_load_vm(struct v3_vm_info * vm, char * store, char * url) { - return v3_chkpt_load_vm(vm, store, url); +int v3_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { + return v3_chkpt_load_vm(vm, store, url, opts); } #ifdef V3_CONFIG_LIVE_MIGRATION -int v3_send_vm(struct v3_vm_info * vm, char * store, char * url) { - return v3_chkpt_send_vm(vm, store, url); +int v3_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { + return v3_chkpt_send_vm(vm, store, url, opts); } -int v3_receive_vm(struct v3_vm_info * vm, char * store, char * url) { - return v3_chkpt_receive_vm(vm, store, url); +int v3_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { + return v3_chkpt_receive_vm(vm, store, url, opts); } #endif diff --git a/palacios/src/palacios/vmm_checkpoint.c b/palacios/src/palacios/vmm_checkpoint.c index 9c55e3f..db9f42f 100644 --- a/palacios/src/palacios/vmm_checkpoint.c +++ b/palacios/src/palacios/vmm_checkpoint.c @@ -666,7 +666,7 @@ static int load_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { } -static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) { +static int load_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) { extern v3_cpu_arch_t v3_mach_type; void * ctx = NULL; char key_name[16]; @@ -773,6 +773,10 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) { } + if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) { + goto donearch; + } + switch (v3_mach_type) { case V3_SVM_CPU: case V3_SVM_REV3_CPU: { @@ -823,6 +827,8 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) { goto loadfailout; } + donearch: + PrintDebug(info->vm_info, info, "Load of core succeeded\n"); v3_print_guest_state(info); @@ -838,7 +844,7 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) { // GEM5 - Hypercall for initiating transfer to gem5 (checkpoint) -static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) { +static int save_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) { extern v3_cpu_arch_t v3_mach_type; void * ctx = NULL; char key_name[16]; @@ -928,6 +934,10 @@ static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) { v3_chkpt_close_ctx(ctx); ctx=0; + if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) { + goto donearch; + } + //Architechture specific code switch (v3_mach_type) { case V3_SVM_CPU: @@ -979,6 +989,8 @@ static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) { goto savefailout; } + + donearch: return 0; @@ -993,7 +1005,7 @@ static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) { // GEM5 - Madhav has debug code here for printing instrucions // -int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) { +int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { struct v3_chkpt * chkpt = NULL; int ret = 0;; int i = 0; @@ -1011,28 +1023,33 @@ int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) { while (v3_raise_barrier(vm, NULL) == -1); } - if ((ret = save_memory(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { + if ((ret = save_memory(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to save memory\n"); goto out; + } } - if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { + if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to save devices\n"); goto out; + } } - if ((ret = save_header(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to save header\n"); goto out; } - - for (i = 0; i < vm->num_cores; i++){ - if ((ret = save_core(&(vm->cores[i]), chkpt)) == -1) { - PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i); - goto out; + + if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { + for (i = 0; i < vm->num_cores; i++){ + if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) { + PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i); + goto out; } + } } out: @@ -1048,7 +1065,7 @@ int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) { } -int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { +int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { struct v3_chkpt * chkpt = NULL; int i = 0; int ret = 0; @@ -1065,15 +1082,18 @@ int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { while (v3_raise_barrier(vm, NULL) == -1); } - if ((ret = load_memory(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { + if ((ret = load_memory(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to load memory\n"); goto out; + } } - - if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { + if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to load devies\n"); goto out; + } } @@ -1083,11 +1103,13 @@ int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { } //per core cloning - for (i = 0; i < vm->num_cores; i++) { - if ((ret = load_core(&(vm->cores[i]), chkpt)) == -1) { - PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i); - goto out; + if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { + for (i = 0; i < vm->num_cores; i++) { + if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) { + PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i); + goto out; } + } } out: @@ -1119,7 +1141,7 @@ int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { -int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url) { +int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { struct v3_chkpt * chkpt = NULL; int ret = 0;; int iter = 0; @@ -1133,10 +1155,10 @@ int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url) { // Currently will work only for shadow paging for (i=0;inum_cores;i++) { - if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING) { - PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n"); - return -1; - } + if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { + PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n"); + return -1; + } } @@ -1148,6 +1170,10 @@ int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url) { return -1; } + if (opts & V3_CHKPT_OPT_SKIP_MEM) { + goto memdone; + } + // In a send, the memory is copied incrementally first, // followed by the remainder of the state @@ -1244,38 +1270,45 @@ int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url) { ret = -1; goto out; } - + + memdone: // save the non-memory state - if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { + if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to save devices\n"); goto out; + } } - if ((ret = save_header(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to save header\n"); goto out; } - for (i = 0; i < vm->num_cores; i++){ - if ((ret = save_core(&(vm->cores[i]), chkpt)) == -1) { - PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i); - goto out; + if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { + for (i = 0; i < vm->num_cores; i++){ + if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) { + PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i); + goto out; } + } } - - stop_time = v3_get_host_time(&(vm->cores[0].time_state)); - PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time); - PrintDebug(vm, VCORE_NONE, "Done sending VM!\n"); - out: - v3_bitmap_deinit(&modified_pages_to_send); + + if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { + stop_time = v3_get_host_time(&(vm->cores[0].time_state)); + PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time); + PrintDebug(vm, VCORE_NONE, "Done sending VM!\n"); + out: + v3_bitmap_deinit(&modified_pages_to_send); + } + chkpt_close(chkpt); return ret; } -int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { +int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) { struct v3_chkpt * chkpt = NULL; int i = 0; int ret = 0; @@ -1283,10 +1316,10 @@ int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { // Currently will work only for shadow paging for (i=0;inum_cores;i++) { - if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING) { - PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n"); - return -1; - } + if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { + PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n"); + return -1; + } } chkpt = chkpt_open(vm, store, url, LOAD); @@ -1297,6 +1330,11 @@ int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { return -1; } + + if (opts & V3_CHKPT_OPT_SKIP_MEM) { + goto memdone; + } + if (v3_bitmap_init(&mod_pgs,vm->mem_size>>12) == -1) { chkpt_close(chkpt); PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n"); @@ -1323,14 +1361,17 @@ int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { goto out; } } + + memdone: - if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) { + if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { + if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to load devices\n"); ret = -1; goto out; + } } - if ((ret = load_header(vm, chkpt)) == -1) { PrintError(vm, VCORE_NONE, "Unable to load header\n"); ret = -1; @@ -1338,13 +1379,15 @@ int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { } //per core cloning - for (i = 0; i < vm->num_cores; i++) { - if ((ret = load_core(&(vm->cores[i]), chkpt)) == -1) { - PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i); - goto out; + if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { + for (i = 0; i < vm->num_cores; i++) { + if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) { + PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i); + goto out; } + } } - + out: if (ret==-1) { PrintError(vm, VCORE_NONE, "Unable to receive VM\n"); @@ -1366,7 +1409,11 @@ int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url) { v3_lower_barrier(vm); } - v3_bitmap_deinit(&mod_pgs); + + if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { + v3_bitmap_deinit(&mod_pgs); + } + chkpt_close(chkpt); return ret;