From: Jack Lange Date: Thu, 27 Oct 2011 22:35:54 +0000 (-0400) Subject: updated file interface to work with earlier 2.6 kernels at least 2.6.32 to ~2.6.35 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=c3b52f20c568ae977924e35340d0cc259634d44f updated file interface to work with earlier 2.6 kernels at least 2.6.32 to ~2.6.35 added directory based checkpoint backend using the file interface --- diff --git a/linux_module/iface-file.c b/linux_module/iface-file.c index 3d8ab4d..be8ed3e 100644 --- a/linux_module/iface-file.c +++ b/linux_module/iface-file.c @@ -81,7 +81,10 @@ static int mkdir_recursive(const char * path, unsigned short perms) { // Ignore empty directories if ((tmp_iter - dirname_ptr) > 1) { - palacios_file_mkdir(tmp_str, perms, 0); + if (palacios_file_mkdir(tmp_str, perms, 0) != 0) { + printk("Could not create directory (%s)\n", tmp_str); + return -1; + } } if (done) { @@ -101,6 +104,7 @@ static int mkdir_recursive(const char * path, unsigned short perms) { } static int palacios_file_mkdir(const char * pathname, unsigned short perms, int recurse) { + /* Welcome to the jungle... */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) /* DO NOT REFERENCE THIS VARIABLE */ @@ -122,7 +126,20 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int #if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) { struct nameidata nd; + + // I'm not 100% sure about the version here, but it was around this time that the API changed +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ret = kern_path_parent(pathname, &nd); +#else + + if (path_lookup(pathname, LOOKUP_DIRECTORY | LOOKUP_FOLLOW, &nd) == 0) { + return 0; + } + + if (path_lookup(pathname, LOOKUP_PARENT | LOOKUP_FOLLOW, &nd) != 0) { + return -1; + } +#endif if (ret != 0) { printk("%s:%d - Error: kern_path_parent() returned error for (%s)\n", __FILE__, __LINE__, @@ -138,7 +155,7 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int dentry = kern_path_create(AT_FDCWD, pathname, &tmp_path, 1); if (IS_ERR(dentry)) { - return -1; + return 0; } path_ptr = &tmp_path; @@ -152,6 +169,7 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int mutex_unlock(&(path_ptr->dentry->d_inode->i_mutex)); path_put(path_ptr); + return ret; } @@ -297,6 +315,8 @@ static int file_init( void ) { V3_Init_File(&palacios_file_hooks); + palacios_file_mkdir("/test/test/test/qr14/acqwe2",0755, 1); + return 0; } @@ -316,6 +336,7 @@ static int guest_file_init(struct v3_guest * guest, void ** vm_data) { *vm_data = state; + return 0; } diff --git a/palacios/src/palacios/vmm_chkpt_stores.h b/palacios/src/palacios/vmm_chkpt_stores.h index 505ef8c..389a0ca 100644 --- a/palacios/src/palacios/vmm_chkpt_stores.h +++ b/palacios/src/palacios/vmm_chkpt_stores.h @@ -179,6 +179,109 @@ register_chkpt_store(keyed_stream_store); +#ifdef V3_CONFIG_FILE +#include + + +struct file_ctx { + v3_file_t file; + uint64_t offset; + char * filename; +}; + + +static void * dir_open_chkpt(char * url, chkpt_mode_t mode) { + if (mode == SAVE) { + if (v3_mkdir(url, 0755, 1) != 0) { + return NULL; + } + } + + return url; +} + + + +static int dir_close_chkpt(void * store_data) { + return 0; +} + +static void * dir_open_ctx(void * store_data, + void * parent_ctx, + char * name) { + + char * url = store_data; + struct file_ctx * ctx = NULL; + + + ctx = V3_Malloc(sizeof(struct file_ctx)); + memset(ctx, 0, sizeof(struct file_ctx)); + + ctx->filename = V3_Malloc(strlen(url) + strlen(name) + 5); + memset(ctx->filename, 0, strlen(url) + strlen(name) + 5); + + snprintf(ctx->filename, strlen(url) + strlen(name) + 5, "%s/%s", url, name); + + + ctx->file = v3_file_open(NULL, ctx->filename, FILE_OPEN_MODE_READ | FILE_OPEN_MODE_WRITE | FILE_OPEN_MODE_CREATE); + + return ctx; +} + +static int dir_close_ctx(void * store_data, void * ctx) { + struct file_ctx * file_ctx = ctx; + + v3_file_close(file_ctx->file); + + V3_Free(file_ctx->filename); + V3_Free(file_ctx); + + return 0; +} + +static int dir_save(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + struct file_ctx * file_ctx = ctx; + uint64_t ret = 0; + + ret = v3_file_write(file_ctx->file, buf, len, file_ctx->offset); + + file_ctx->offset += ret; + + return 0; +} + +static int dir_load(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + struct file_ctx * file_ctx = ctx; + uint64_t ret = 0; + + ret = v3_file_read(file_ctx->file, buf, len, file_ctx->offset); + + file_ctx->offset += ret; + + return 0; +} + + +static struct chkpt_interface dir_store = { + .name = "DIR", + .open_chkpt = dir_open_chkpt, + .close_chkpt = dir_close_chkpt, + .open_ctx = dir_open_ctx, + .close_ctx = dir_close_ctx, + .save = dir_save, + .load = dir_load +}; + +register_chkpt_store(dir_store); + + + +#endif + + +