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.


User utils for memory offlining and VM creation with binding
Ferrol Aderholdt [Fri, 22 Jun 2012 18:46:27 +0000 (13:46 -0500)]
linux_usr/Makefile
linux_usr/v3_create_bind.c [new file with mode: 0644]
linux_usr/v3_mem_free.c [new file with mode: 0644]

index 1a0be11..f459a1e 100644 (file)
@@ -11,7 +11,9 @@ STATIC = 1
 # Executables that implement core functionality
 #
 BASE_EXECS =   v3_mem \
+                v3_mem_free \
                v3_create \
+                v3_create_bind \
                v3_free  \
                v3_launch \
                v3_stop   \
diff --git a/linux_usr/v3_create_bind.c b/linux_usr/v3_create_bind.c
new file mode 100644 (file)
index 0000000..feaf170
--- /dev/null
@@ -0,0 +1,206 @@
+/* 
+ * V3 Creation with Binding utility
+ * (c) Jack lange, 2010
+ * (c) Ferrol Aderholdt, 2012 
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int read_file(int fd, int size, unsigned char * buf);
+
+/* loop over the .dat/.img file that is in memory and look for the xml */
+static int find_starting_point(unsigned char * buf) {
+    int i = 0;
+    for(;i<32;i++) {
+       if(*(buf+i) == '<') 
+           /* Looking for <vm class="PC"> portion of xml file. */
+           if(*(buf+i+1) == 'v')
+               return i;
+    }
+    
+    return -1;
+}
+
+/* simple override option that just overwrites the characters in memory with
+   a new value. Supports string lengths of equal size or lesser size, but not
+   more than size. Kind of a rough hack to get it done, but should work for 
+   it's goal of changing mac addresses on the fly. */
+int override_option(unsigned char * buf, char * option, char * value) {
+    int starting_point = find_starting_point(buf);
+    unsigned char * ptr;
+    unsigned char * end;
+    int i = 0;
+    
+    if(starting_point == -1) {
+       fprintf(stderr, "Could not find a starting point to make ");
+       fprintf(stderr, "modifications to the xml\n");
+       return -1;
+    }
+    
+    ptr = strstr(buf+starting_point, option);
+    /* essentially, return if the option isn't present */
+    if(ptr == NULL)
+       return -1;
+    
+    /* find end of xml tag */
+    ptr = strchr(buf+(ptr-buf), '>');
+    end = strchr(buf+(ptr-buf), '<');
+    
+    if(strlen(value) > (end-ptr-1)) {
+       fprintf(stderr, "Override option %s length is longer than currentlyin VM image file. This is not currently supported.\n", option);
+       return -1;
+    }
+    
+    for(i=0;i<strlen(value);i++) {
+       ptr[i+1] = value[i];
+    }
+    
+    /* the new option is smaller than the old one */
+    if(strlen(value) < (end-ptr-1)) {
+       int j = 0;
+       ptr[i+1] = '<';
+       i++;
+       ptr[i+1] = '/';
+       i++;
+       for(j;j<strlen(option);j++,i++) {
+           ptr[i+1] = option[j];
+       }
+       ptr[i+1] = '>';
+       i++;
+       for(j=0;j< (end-ptr-1)-strlen(value);j++,i++) {
+           ptr[i+1] = ' ';
+       }
+    }
+    
+    return 0;
+}
+
+
+
+
+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;
+    int dev_idx = 0;
+
+    memset(&guest_img, 0, sizeof(struct v3_guest_img));
+
+    if (argc <= 2) {
+       printf("usage: v3_create_bind <guest_img> <vm name> [override options]\n");
+       printf(" override options are of the form  KEY=VALUE\n");
+       return -1;
+    }
+
+    printf("Creating guest: %s\n", filename);
+
+    guest_fd = open(filename, O_RDONLY); 
+
+    if (guest_fd == -1) {
+       printf("Error Opening guest image: %s\n", filename);
+       return -1;
+    }
+
+    if (fstat(guest_fd, &guest_stats) == -1) {
+       printf("ERROR: Could not stat guest image file -- %s\n", filename);
+       return -1;
+    }
+
+    
+    guest_img.size = guest_stats.st_size;
+    
+    // load guest image into user memory
+    guest_img.guest_data = malloc(guest_img.size);
+
+    read_file(guest_fd, guest_img.size, guest_img.guest_data);
+    
+    close(guest_fd);
+
+    printf("Loaded guest image. Binding now.\n");
+
+    if(argc > 3) {
+       /* these are options. parse them and override the xml */
+       int i = 0;
+       for(i=3;i<argc;i++) {
+           char * argv_copy = malloc(strlen(argv[i]));
+           char * option;
+           char * value;
+           
+           strcpy(argv_copy, argv[i]);
+           option = strtok(argv_copy, "=");
+           value = strtok(NULL, "=");
+           
+           printf("Binding \"%s\" to \"%s\"\n",
+                  option, value);
+           override_option(guest_img.guest_data, option, value);
+           free(argv_copy);
+       }
+    }
+    
+    printf("Bound guest image.  Launching to V3Vee\n");
+    
+    strncpy(guest_img.name, 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); 
+
+
+    if (dev_idx < 0) {
+       printf("Error (%d) creating VM\n", dev_idx);
+       return -1;
+    }
+
+    printf("VM (%s) created at /dev/v3-vm%d\n", name, dev_idx);
+
+    /* Close the file descriptor.  */ 
+    close(v3_fd); 
+
+
+    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_mem_free.c b/linux_usr/v3_mem_free.c
new file mode 100644 (file)
index 0000000..31a775e
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(void) 
+{
+    FILE * fp;
+    char * filepath = "/proc/v3vee/v3-mem";
+    char line[255];
+    unsigned long base_addr = 0;
+    unsigned long long num_pages = 0;
+    unsigned long amount_allocated = 0;
+    unsigned long long block_size = 0;
+    int i = 0;
+    
+    fp = fopen(filepath, "r");
+    if(fp == NULL) {
+       fprintf(stderr, "Could not open %s\n", filepath);
+       return -1;
+    }
+    memset(line, 0, 255);
+    fgets(line, 255, fp);
+    base_addr = strtoul(line, NULL, 16);
+    base_addr = base_addr / (1024*1024);
+    memset(line, 0, 255);
+    fgets(line, 255, fp);
+    num_pages = strtoull(line, NULL, 10);
+    amount_allocated = (num_pages*4096)/(1024*1024);
+    
+    fclose(fp);
+    
+    /* now get the block size */
+    fp = fopen("/sys/devices/system/memory/block_size_bytes", "r");
+    if(fp == NULL) {
+       fprintf(stderr, "Cannot lookup bytes per block size\n");
+       return -1;
+    }
+    memset(line, 0, 255);
+    fgets(line, 255, fp);
+    block_size = strtoull(line, NULL, 16);
+    block_size = block_size / (1024*1024); //convert to MB
+    fclose(fp);
+    
+    /* turn base_addr into the region number */
+    base_addr = base_addr / block_size;
+    
+    for(i=0;i< (amount_allocated / block_size); i++) {
+       char path[50];
+       
+       memset(path, 0, 50);
+       sprintf(path,"/sys/devices/system/memory/memory%d/state", 
+               base_addr);
+       fp = fopen(path, "w+");
+       if(fp == NULL) {
+           fprintf(stderr, "Could not open %s\n", path);
+           return -1;
+       }
+       printf("Sending \"online\" to memory%d\n", base_addr);
+       fprintf(fp, "online");
+       fclose(fp);
+       base_addr++;
+    }
+    
+    return 0;
+}