From: Jack Lange Date: Fri, 16 Sep 2011 21:50:07 +0000 (-0400) Subject: hooking checkpoints into vmm execution X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a9a6c3664c8fdbdb9841a55d1a2fca7f4fa8f5de hooking checkpoints into vmm execution --- diff --git a/linux_module/iface-file.c b/linux_module/iface-file.c index 396183b..965023a 100644 --- a/linux_module/iface-file.c +++ b/linux_module/iface-file.c @@ -63,6 +63,11 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat } else if (mode & FILE_OPEN_MODE_WRITE) { pfile->mode = O_WRONLY; } + + if (mode & FILE_OPEN_MODE_CREATE) { + pfile->mode |= O_CREAT; + } + pfile->filp = filp_open(path, pfile->mode, 0); diff --git a/palacios/include/interfaces/vmm_file.h b/palacios/include/interfaces/vmm_file.h index 9776913..46b89b1 100644 --- a/palacios/include/interfaces/vmm_file.h +++ b/palacios/include/interfaces/vmm_file.h @@ -39,6 +39,7 @@ uint64_t v3_file_write(v3_file_t file, uint8_t * buf, uint64_t len, uint64_t off #define FILE_OPEN_MODE_READ (1 << 0) #define FILE_OPEN_MODE_WRITE (1 << 1) +#define FILE_OPEN_MODE_CREATE (1 << 2) struct v3_file_hooks { diff --git a/palacios/include/palacios/vmm_checkpoint.h b/palacios/include/palacios/vmm_checkpoint.h index 4281d5e..d62d98f 100644 --- a/palacios/include/palacios/vmm_checkpoint.h +++ b/palacios/include/palacios/vmm_checkpoint.h @@ -35,6 +35,8 @@ struct v3_chkpt_ctx { }; + + int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf); int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf); @@ -44,7 +46,8 @@ struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt 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_init_checkpoint(); +int V3_deinit_checkpoint(); #endif diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 14a0d2f..4b9083b 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -33,6 +33,10 @@ #include #endif +#ifdef V3_CONFIG_CHECKPOINT +#include +#endif + v3_cpu_arch_t v3_cpu_types[V3_CONFIG_MAX_CPUS]; struct v3_os_hooks * os_hooks = NULL; @@ -119,6 +123,10 @@ void Init_V3(struct v3_os_hooks * hooks, int num_cpus) { V3_init_symmod(); #endif +#ifdef V3_CONFIG_CHECKPOINT + V3_init_checkpoint(); +#endif + #ifdef V3_CONFIG_MULTITHREAD_OS @@ -149,6 +157,10 @@ void Shutdown_V3() { V3_deinit_symmod(); #endif +#ifdef V3_CONFIG_CHECKPOINT + V3_deinit_checkpoint(); +#endif + #ifdef V3_CONFIG_MULTITHREAD_OS if ((os_hooks) && (os_hooks->call_on_cpu)) { diff --git a/palacios/src/palacios/vmm_checkpoint.c b/palacios/src/palacios/vmm_checkpoint.c index ef4bec1..8f5e5ac 100644 --- a/palacios/src/palacios/vmm_checkpoint.c +++ b/palacios/src/palacios/vmm_checkpoint.c @@ -58,9 +58,58 @@ struct v3_chkpt { }; + + +static uint_t store_hash_fn(addr_t key) { + char * name = (char *)key; + return v3_hash_buffer((uint8_t *)name, strlen(name)); +} + +static int store_eq_fn(addr_t key1, addr_t key2) { + char * name1 = (char *)key1; + char * name2 = (char *)key2; + + return (strcmp(name1, name2) == 0); +} + + + #include "vmm_chkpt_stores.h" +int V3_init_checkpoint() { + extern struct chkpt_interface * __start__v3_chkpt_stores[]; + extern struct chkpt_interface * __stop__v3_chkpt_stores[]; + struct chkpt_interface ** tmp_store = __start__v3_chkpt_stores; + int i = 0; + + store_table = v3_create_htable(0, store_hash_fn, store_eq_fn); + + while (tmp_store != __stop__v3_chkpt_stores) { + V3_Print("Registering Checkpoint Backing Store (%s)\n", (*tmp_store)->name); + + if (v3_htable_search(store_table, (addr_t)((*tmp_store)->name))) { + PrintError("Multiple instances of Checkpoint backing Store (%s)\n", (*tmp_store)->name); + return -1; + } + + if (v3_htable_insert(store_table, (addr_t)((*tmp_store)->name), (addr_t)(*tmp_store)) == 0) { + PrintError("Could not register Checkpoint backing store (%s)\n", (*tmp_store)->name); + return -1; + } + + tmp_store = &(__start__v3_chkpt_stores[++i]); + } + + return 0; +} + +int V3_deinit_checkpoint() { + v3_free_htable(store_table, 0, 0); + return 0; +} + + static char svm_chkpt_header[] = "v3vee palacios checkpoint version: x.x, SVM x.x"; static char vmx_chkpt_header[] = "v3vee palacios checkpoint version: x.x, VMX x.x"; @@ -73,23 +122,54 @@ static int chkpt_close(struct v3_chkpt * chkpt) { } -static struct v3_chkpt * chkpt_open(char * store, char * url, chkpt_mode_t mode) { +static struct v3_chkpt * chkpt_open(struct v3_vm_info * vm, char * store, char * url, chkpt_mode_t mode) { + struct chkpt_interface * iface = NULL; + struct v3_chkpt * chkpt = NULL; + void * store_data = NULL; + + iface = (void *)v3_htable_search(store_table, (addr_t)store); - // search for checkpoint interface + if (iface == NULL) { + V3_Print("Error: Could not locate Checkpoint interface for store (%s)\n", store); + return NULL; + } + + store_data = iface->open_chkpt(url, mode); + + if (store_data == NULL) { + PrintError("Could not open url (%s) for backing store (%s)\n", url, store); + return NULL; + } + + + chkpt = V3_Malloc(sizeof(struct v3_chkpt)); - PrintError("Not yet implemented\n"); - return NULL; + if (!chkpt) { + PrintError("Could not allocate checkpoint state\n"); + return NULL; + } + + chkpt->interface = iface; + chkpt->vm = vm; + chkpt->store_data = store_data; + + return chkpt; } struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt_ctx * parent, char * name) { struct v3_chkpt_ctx * ctx = V3_Malloc(sizeof(struct v3_chkpt_ctx)); + void * parent_store_ctx = NULL; memset(ctx, 0, sizeof(struct v3_chkpt_ctx)); ctx->chkpt = chkpt; ctx->parent = parent; - ctx->store_ctx = chkpt->interface->open_ctx(chkpt->store_data, parent->store_ctx, name); + if (parent) { + parent_store_ctx = parent->store_ctx; + } + + ctx->store_ctx = chkpt->interface->open_ctx(chkpt->store_data, parent_store_ctx, name); return ctx; } @@ -137,12 +217,7 @@ static int load_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { ret = v3_chkpt_load(ctx, "memory_img", vm->mem_size, guest_mem_base); v3_chkpt_close_ctx(ctx); - if (ret == 0) { - PrintError("Error Loading VM Memory\n"); - return -1; - } - - return 0; + return ret; } @@ -153,18 +228,13 @@ static int save_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { guest_mem_base = V3_VAddr((void *)vm->mem_map.base_region.host_addr); - ctx = v3_chkpt_open_ctx(chkpt, NULL, "memory_img"); + ctx = v3_chkpt_open_ctx(chkpt, NULL,"memory_img"); ret = v3_chkpt_save(ctx, "memory_img", vm->mem_size, guest_mem_base); v3_chkpt_close_ctx(ctx); - if (ret == 0) { - PrintError("Error Saving VM Memory\n"); - return -1; - } - - return 0; + return ret; } int save_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { @@ -390,7 +460,7 @@ int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) { int ret = 0;; int i = 0; - chkpt = chkpt_open(store, url, SAVE); + chkpt = chkpt_open(vm, store, url, SAVE); if (chkpt == NULL) { PrintError("Error creating checkpoint store\n"); @@ -445,7 +515,7 @@ int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { int i = 0; int ret = 0; - chkpt = chkpt_open(store, url, LOAD); + chkpt = chkpt_open(vm, store, url, LOAD); if (chkpt == NULL) { PrintError("Error creating checkpoint store\n"); @@ -505,43 +575,3 @@ int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) { -static uint_t store_hash_fn(addr_t key) { - char * name = (char *)key; - return v3_hash_buffer((uint8_t *)name, strlen(name)); -} - -static int store_eq_fn(addr_t key1, addr_t key2) { - char * name1 = (char *)key1; - char * name2 = (char *)key2; - - return (strcmp(name1, name2) == 0); -} - - - -int V3_init_checkpoint() { - extern struct chkpt_interface * __start__v3_chkpt_stores[]; - extern struct chkpt_interface * __stop__v3_chkpt_stores[]; - struct chkpt_interface ** tmp_store = __start__v3_chkpt_stores; - int i = 0; - - store_table = v3_create_htable(0, store_hash_fn, store_eq_fn); - - while (tmp_store != __stop__v3_chkpt_stores) { - V3_Print("Registering Extension (%s)\n", (*tmp_store)->name); - - if (v3_htable_search(store_table, (addr_t)((*tmp_store)->name))) { - PrintError("Multiple instances of Extension (%s)\n", (*tmp_store)->name); - return -1; - } - - if (v3_htable_insert(store_table, (addr_t)((*tmp_store)->name), (addr_t)(*tmp_store)) == 0) { - PrintError("Could not register Extension (%s)\n", (*tmp_store)->name); - return -1; - } - - tmp_store = &(__start__v3_chkpt_stores[++i]); - } - - return 0; -} diff --git a/palacios/src/palacios/vmm_chkpt_stores.h b/palacios/src/palacios/vmm_chkpt_stores.h index 5a23e2d..505ef8c 100644 --- a/palacios/src/palacios/vmm_chkpt_stores.h +++ b/palacios/src/palacios/vmm_chkpt_stores.h @@ -40,6 +40,76 @@ static struct {} null_store __attribute__((__used__)) \ + +#include + + +static void * debug_open_chkpt(char * url, chkpt_mode_t mode) { + + if (mode == LOAD) { + V3_Print("Cannot load from debug store\n"); + return NULL; + } + + V3_Print("Opening Checkpoint: %s\n", url); + + return (void *)1; +} + + + +static int debug_close_chkpt(void * store_data) { + V3_Print("Closing Checkpoint\n"); + return 0; +} + +static void * debug_open_ctx(void * store_data, + void * parent_ctx, + char * name) { + V3_Print("[%s]\n", name); + return (void *)1; +} + +static int debug_close_ctx(void * store_data, void * ctx) { + V3_Print("[CLOSE]\n"); + return 0; +} + +static int debug_save(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + V3_Print("%s:\n", tag); + + if (len > 100) { + len = 100; + } + + v3_dump_mem(buf, len); + + return 0; +} + +static int debug_load(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + V3_Print("Loading not supported !!!\n"); + return 0; +} + + +static struct chkpt_interface debug_store = { + .name = "DEBUG", + .open_chkpt = debug_open_chkpt, + .close_chkpt = debug_close_chkpt, + .open_ctx = debug_open_ctx, + .close_ctx = debug_close_ctx, + .save = debug_save, + .load = debug_load +}; + +register_chkpt_store(debug_store); + + + + #ifdef V3_CONFIG_KEYED_STREAMS #include @@ -112,4 +182,5 @@ register_chkpt_store(keyed_stream_store); + #endif