Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Checkpointing and migration now support options, the first of which are: skipping...
Peter Dinda [Mon, 18 Mar 2013 19:05:08 +0000 (14:05 -0500)]
linux_module/palacios.h
linux_module/vm.c
linux_usr/v3_ctrl.h
linux_usr/v3_load.c
linux_usr/v3_receive.c
linux_usr/v3_save.c
linux_usr/v3_send.c
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_checkpoint.h
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_checkpoint.c

index 99ef5ef..8810f44 100644 (file)
@@ -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));
 
 
index 54d5efd..b7425e4 100644 (file)
@@ -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;
            }
index e81968c..929d7e6 100644 (file)
@@ -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));
 
 
index a409a2d..7e3e212 100644 (file)
@@ -32,7 +32,13 @@ int main(int argc, char* argv[]) {
     char * vm_dev = NULL;
 
     if (argc < 4) {
-       printf("usage: v3_load <vm_device> <store> <url>\n");
+       printf("usage: v3_load <vm_device> <store> <url> [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);
index 9c3fafd..153ccd9 100644 (file)
@@ -32,7 +32,13 @@ int main(int argc, char* argv[]) {
     char * vm_dev = NULL;
 
     if (argc < 4) {
-       printf("Usage: ./v3_receive <vm_device> <store> <url>\n");
+       printf("Usage: ./v3_receive <vm_device> <store> <url> [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);
index 46ae513..4749c5a 100644 (file)
@@ -31,8 +31,16 @@ int main(int argc, char* argv[]) {
     int vm_fd;
     char * vm_dev = NULL;
 
+    
+
     if (argc < 4) {
-       printf("usage: v3_save <vm_device> <store> <url>\n");
+       printf("usage: v3_save <vm_device> <store> <url> [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);
index fcb71c4..523be30 100644 (file)
@@ -32,7 +32,13 @@ int main(int argc, char* argv[]) {
     char * vm_dev = NULL;
 
     if (argc < 4) {
-       printf("Usage: ./v3_send <vm_device> <store> <url>\n");
+       printf("Usage: ./v3_send <vm_device> <store> <url> [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);
index 083644e..5379928 100644 (file)
@@ -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);
 
index 3b1a06e..8bd5f5a 100644 (file)
@@ -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();
index 6e32e88..61aa245 100644 (file)
@@ -720,23 +720,23 @@ int v3_get_state_vm(struct v3_vm_info *vm, struct v3_vm_state *s)
 #ifdef V3_CONFIG_CHECKPOINT
 #include <palacios/vmm_checkpoint.h>
 
-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
 
index 9c55e3f..db9f42f 100644 (file)
@@ -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;i<vm->num_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;i<vm->num_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;