From: Kyle Hale Date: Sat, 28 Jul 2012 20:46:05 +0000 (-0500) Subject: repurpose v3_ctrl.c as a utility library for palacios userspace progs X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=008fdde9a6a6ec65b7647d9eec487448094d7f18 repurpose v3_ctrl.c as a utility library for palacios userspace progs I've taken some common idioms used in a lot of the userspace utilities and put them in a (for now, static) library that all programs can utilize. One example: when running an ioctl, it's no longer necessary to open the vm device, close it, etc. This is taken care of by v3_vm_ioctl. This should give us some more code sharing and make the userspace utilities quicker to write and a bit smaller. For now, I've modified v3_free, v3_launch, v3_stop, and v3_create to use this library, so you can look to those for examples. --- diff --git a/linux_usr/Makefile b/linux_usr/Makefile index 888e956..dc1ab05 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -62,7 +62,7 @@ COPIED_EXECS = v3_x0vncserver # # Libraries that we need to build # -LIBS = libv3_user_host_dev.a libv3_user_keyed_stream.a +LIBS = libv3_user_host_dev.a libv3_user_keyed_stream.a libv3_ctrl.a BUILD_EXECS = $(BASE_EXECS) $(EXAMPLE_EXECS) $(EXPERIMENTAL_EXECS) BUILD_LIBS = $(LIBS) @@ -82,11 +82,16 @@ AR = ar all: $(BUILD_EXECS) $(BUILD_LIBS) $(COPIED_EXECS) +libv3_ctrl.a : v3_ctrl.c v3_ctrl.h + $(CC) $(CFLAGS) -I../linux_module -c v3_ctrl.c + $(AR) ruv libv3_ctrl.a v3_ctrl.o + rm -rf v3_ctrl.o + # # Most tools compile in a straightforward way # -% :: %.c v3_ctrl.h - $(CC) $(CFLAGS) $< -o $@ +% :: %.c v3_ctrl.h libv3_ctrl.a + $(CC) $(CFLAGS) $< -lv3_ctrl -L. -o $@ # @@ -102,8 +107,8 @@ v3_cons: v3_cons.c v3_cons_sc: v3_cons_sc.c $(CC) $(CFLAGS) $(CURSES_CFLAGS) $< -lcurses -o $@ -v3_create: v3_create.c ezxml.c - $(CC) $(CFLAGS) $^ -o $@ +v3_create: v3_create.c ezxml.c libv3_ctrl.a + $(CC) $(CFLAGS) $^ -lv3_ctrl -L. -o $@ diff --git a/linux_usr/v3_create.c b/linux_usr/v3_create.c index 02bb873..8131df3 100644 --- a/linux_usr/v3_create.c +++ b/linux_usr/v3_create.c @@ -17,33 +17,12 @@ #include "v3_ctrl.h" #include "ezxml.h" -struct cfg_value { - char * tag; - char * value; -}; - -struct xml_option { - char * tag; - ezxml_t location; - struct xml_option * next; -}; - - -struct file_info { - int size; - char filename[2048]; - char id[256]; -}; #define MAX_FILES 256 unsigned long long num_files = 0; struct file_info files[MAX_FILES]; -int read_file(int fd, int size, unsigned char * buf); - - - int create_vm(char * vm_name, void * img_data, unsigned int img_size) { struct v3_guest_img guest_img; int v3_fd = 0; @@ -55,16 +34,7 @@ int create_vm(char * vm_name, void * img_data, unsigned int img_size) { guest_img.guest_data = img_data; strncpy(guest_img.name, vm_name, 127); - - v3_fd = open(v3_dev, O_RDONLY); - - if (v3_fd == -1) { - printf("Error opening V3Vee control device\n"); - return -1; - } - - dev_idx = ioctl(v3_fd, V3_CREATE_GUEST, &guest_img); - + dev_idx = v3_dev_ioctl(V3_CREATE_GUEST, &guest_img); if (dev_idx < 0) { printf("Error (%d) creating VM\n", dev_idx); @@ -72,10 +42,6 @@ int create_vm(char * vm_name, void * img_data, unsigned int img_size) { } printf("VM (%s) created at /dev/v3-vm%d\n", vm_name, dev_idx); - - /* Close the file descriptor. */ - close(v3_fd); - return 0; } @@ -103,7 +69,7 @@ int load_image(char * vm_name, char * filename) { // load guest image into user memory img_data = malloc(img_size); - read_file(guest_fd, img_size, img_data); + v3_read_file(guest_fd, img_size, img_data); close(guest_fd); @@ -346,7 +312,7 @@ int build_image(char * vm_name, char * filename, struct cfg_value * cfg_vals, in return -1; } - read_file(fd, files[i].size, (unsigned char *)(guest_img_data + offset)); + v3_read_file(fd, files[i].size, (unsigned char *)(guest_img_data + offset)); close(fd); @@ -365,8 +331,6 @@ int build_image(char * vm_name, char * filename, struct cfg_value * cfg_vals, in - - int main(int argc, char** argv) { char * filename = NULL; char * name = NULL; @@ -383,10 +347,8 @@ int main(int argc, char** argv) { } } - if (argc - optind + 1 < 3) { - printf("usage: v3_create [-b] [cfg options]\n"); - return -1; - } + if (argc - optind + 1 < 3) + v3_usage("[-b] [cfg options]\n"); filename = argv[optind]; name = argv[optind + 1]; @@ -436,28 +398,3 @@ int main(int argc, char** argv) { return 0; } - - - -int read_file(int fd, int size, unsigned char * buf) { - int left_to_read = size; - int have_read = 0; - - while (left_to_read != 0) { - int bytes_read = read(fd, buf + have_read, left_to_read); - - if (bytes_read <= 0) { - break; - } - - have_read += bytes_read; - left_to_read -= bytes_read; - } - - if (left_to_read != 0) { - printf("Error could not finish reading file\n"); - return -1; - } - - return 0; -} diff --git a/linux_usr/v3_ctrl.c b/linux_usr/v3_ctrl.c index 984045b..0183a95 100644 --- a/linux_usr/v3_ctrl.c +++ b/linux_usr/v3_ctrl.c @@ -1,6 +1,7 @@ /* - * V3 Control utility + * V3 Control Library * (c) Jack lange, 2010 + * Kyle Hale, 2012 */ @@ -10,101 +11,142 @@ #include #include #include +#include #include #include #include "v3_ctrl.h" -int read_file(int fd, int size, unsigned char * buf); -int main(int argc, char* argv[]) { - char * filename = argv[1]; - char * name = argv[2]; - int guest_fd = 0; - int v3_fd = 0; - struct v3_guest_img guest_img; - struct stat guest_stats; - - memset(&guest_img, 0, sizeof(struct v3_guest_img)); +/* + * create a file-backed memory region + */ +void * v3_mmap_file (const char * filename, int prot, int flags) { + int fd; + struct stat st; + void * m; + + fd = open(filename, O_RDONLY); + if (!fd) { + fprintf(stderr, "Error opening file for mapping: %s\n", filename); + return NULL; + } - if (argc <= 2) { - printf("usage: v3_ctrl \n"); - return -1; + fstat(fd, &st); + + if ((m = mmap(NULL, st.st_size, prot, flags, fd, 0)) == MAP_FAILED) { + fprintf(stderr, "Error mapping file (%s)\n", filename); + close(fd); + return NULL; } - printf("Launching guest: %s\n", filename); + close(fd); + return m; +} - guest_fd = open(filename, O_RDONLY); - if (guest_fd == -1) { - printf("Error Opening guest image: %s\n", filename); - return -1; +/* + * read a file into a buffer + */ +int v3_read_file (int fd, int size, unsigned char * buf) { + int left_to_read = size; + int have_read = 0; + + while (left_to_read != 0) { + int bytes_read = read(fd, buf + have_read, left_to_read); + + if (bytes_read <= 0) { + break; + } + + have_read += bytes_read; + left_to_read -= bytes_read; } - if (fstat(guest_fd, &guest_stats) == -1) { - printf("ERROR: Could not stat guest image file -- %s\n", filename); + if (left_to_read != 0) { + fprintf(stderr, "Error could not finish reading file\n"); return -1; } - - - guest_img.size = guest_stats.st_size; - // load guest image into user memory - guest_img.guest_data = malloc(guest_img.size); - if (!guest_img.guest_data) { - printf("ERROR: Could not allocate memory for guest image\n"); + return 0; +} + + +/* + * perform an ioctl on v3vee device + */ +int v3_dev_ioctl (int request, void * arg) { + int fd, ret; + + fd = open(v3_dev, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Error opening V3Vee control device\n"); return -1; } - read_file(guest_fd, guest_img.size, guest_img.guest_data); - - close(guest_fd); + ret = ioctl(fd, request, arg); + + if (ret < 0) + fprintf(stderr, "IOCTL error on V3Vee control device (%d)\n", ret); - printf("Loaded guest image. Launching to V3Vee\n"); - - strncpy(guest_img.name, name, 127); + close(fd); + return ret; +} - v3_fd = open(v3_dev, O_RDONLY); - if (v3_fd == -1) { - printf("Error opening V3Vee control device\n"); - return -1; +/* + * perform an ioctl on arbitrary VM device + */ +int v3_vm_ioctl (const char * filename, + int request, + void * arg) { + int fd, ret; + + fd = open(filename, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Error opening V3Vee VM device: %s\n", filename); + return -1; } - ioctl(v3_fd, V3_START_GUEST, &guest_img); + ret = ioctl(fd, request, arg); + if (ret < 0) + fprintf(stderr, "IOCTL error on device %s (%d)\n", filename, ret); + close(fd); + return ret; +} - /* Close the file descriptor. */ - close(v3_fd); - +/* + * launch a VM with VM device path + */ +int launch_vm (const char * filename) { + int err; - return 0; -} + printf("Launching VM (%s)\n", filename); + err = v3_vm_ioctl(filename, V3_VM_LAUNCH, NULL); + if (err < 0) { + fprintf(stderr, "Error launching VM (%s)\n", filename); + return -1; + } + return 0; +} -int read_file(int fd, int size, unsigned char * buf) { - int left_to_read = size; - int have_read = 0; - while (left_to_read != 0) { - int bytes_read = read(fd, buf + have_read, left_to_read); +/* + * stop a VM with VM device path + */ +int stop_vm (const char * filename) { + int err; - if (bytes_read <= 0) { - break; - } + printf("Stopping VM (%s)\n", filename); - have_read += bytes_read; - left_to_read -= bytes_read; - } + if (v3_vm_ioctl(filename, V3_VM_STOP, NULL) < 0) + return -1; - if (left_to_read != 0) { - printf("Error could not finish reading file\n"); - return -1; - } - return 0; } diff --git a/linux_usr/v3_ctrl.h b/linux_usr/v3_ctrl.h index aae3af6..a210013 100644 --- a/linux_usr/v3_ctrl.h +++ b/linux_usr/v3_ctrl.h @@ -6,12 +6,16 @@ #ifndef _v3_ctrl_h #define _v3_ctrl_h +#include +#include +#include "ezxml.h" /* Global Control IOCTLs */ #define V3_CREATE_GUEST 12 #define V3_FREE_GUEST 13 #define V3_ADD_MEMORY 50 +#define V3_RESET_MEMORY 51 #define V3_ADD_PCI_HW_DEV 55 #define V3_ADD_PCI_USER_DEV 56 @@ -84,5 +88,46 @@ struct v3_hw_pci_dev { unsigned int func; } __attribute__((packed)); +#define V3VEE_STR "\n\n" \ + "The V3Vee Project (c) 2012\n" \ + "\thttp://v3vee.org\n" \ + "\n\n" + +#define v3_usage(fmt, args...) \ +{ \ + printf(("\nUsage: %s " fmt V3VEE_STR), argv[0], ##args); \ + exit(0); \ +} + + +int v3_dev_ioctl (int req, void * arg); +int v3_vm_ioctl (const char * filename, + int req, + void * arg); +void * v3_mmap_file (const char * filename, int prot, int flags); +int v3_read_file (int fd, int size, unsigned char * buf); + +int launch_vm (const char * filename); +int stop_vm (const char * filename); + + +/* XML-related structs */ +struct cfg_value { + char * tag; + char * value; +}; + +struct xml_option { + char * tag; + ezxml_t location; + struct xml_option * next; +}; + + +struct file_info { + int size; + char filename[2048]; + char id[256]; +}; #endif diff --git a/linux_usr/v3_free.c b/linux_usr/v3_free.c index 1aa4d7a..4746c21 100644 --- a/linux_usr/v3_free.c +++ b/linux_usr/v3_free.c @@ -3,50 +3,27 @@ * (c) Jack lange, 2011 */ - -#include -#include -#include -#include -#include -#include -#include #include #include "v3_ctrl.h" int main(int argc, char* argv[]) { - int vm_fd = 0; unsigned long vm_idx = 0; int ret; - - if (argc <= 1) { - printf("usage: v3_free \n"); - return -1; - } + if (argc <= 1) + v3_usage("\n"); vm_idx = strtol(argv[1], NULL, 0); printf("Freeing VM %d\n", vm_idx); - vm_fd = open("/dev/v3vee", O_RDONLY); - - if (vm_fd == -1) { - printf("Error opening V3Vee VM device\n"); - return -1; - } - - ret = ioctl(vm_fd, V3_FREE_GUEST, vm_idx); - if (ret < 0) { - printf("Error freeing VM %d\n", vm_idx); + if (v3_dev_ioctl(V3_FREE_GUEST, vm_idx) < 0) { + fprintf(stderr, "Error freeing VM %d\n", vm_idx); return -1; } - /* Close the file descriptor. */ - close(vm_fd); - return 0; } diff --git a/linux_usr/v3_launch.c b/linux_usr/v3_launch.c index 7419a6b..217d104 100644 --- a/linux_usr/v3_launch.c +++ b/linux_usr/v3_launch.c @@ -3,52 +3,16 @@ * (c) Jack lange, 2010 */ - -#include -#include -#include -#include -#include -#include -#include -#include - #include "v3_ctrl.h" int main(int argc, char* argv[]) { - int vm_fd = 0; char * filename = argv[1]; - int err; - - if (argc <= 1) { - printf("usage: v3_launch \n"); - return -1; - } - - printf("Launching VM (%s)\n", filename); - - vm_fd = open(filename, O_RDONLY); - - if (vm_fd == -1) { - printf("Error opening V3Vee VM device\n"); - return -1; - } - - err = ioctl(vm_fd, V3_VM_LAUNCH, NULL); - if (err < 0) { - printf("Error launching VM\n"); - return -1; - } + if (argc <= 1) + v3_usage("\n"); - - /* Close the file descriptor. */ - close(vm_fd); - - + launch_vm(filename); return 0; } - - diff --git a/linux_usr/v3_stop.c b/linux_usr/v3_stop.c index adb69b1..86e5752 100644 --- a/linux_usr/v3_stop.c +++ b/linux_usr/v3_stop.c @@ -2,46 +2,19 @@ * V3 Control utility * (c) Jack lange, 2010 */ - - -#include -#include -#include -#include -#include -#include -#include -#include - #include "v3_ctrl.h" int main(int argc, char* argv[]) { - int vm_fd = 0; char * filename = argv[1]; - if (argc <= 1) { - printf("usage: v3_stop \n"); - return -1; - } + if (argc <= 1) + v3_usage("\n"); - printf("Stopping VM (%s)\n", filename); - - vm_fd = open(filename, O_RDONLY); - - if (vm_fd == -1) { - printf("Error opening V3Vee VM device\n"); - return -1; + if (stop_vm(filename) < 0) { + fprintf(stderr, "Error stopping VM (%s)\n", filename); + return -1; } - ioctl(vm_fd, V3_VM_STOP, NULL); - - - - /* Close the file descriptor. */ - close(vm_fd); - - - return 0; }