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
[palacios.git] / linux_usr / v3_create_bind.c
1 /* 
2  * V3 Creation with Binding utility
3  * (c) Jack lange, 2010
4  * (c) Ferrol Aderholdt, 2012 
5  */
6
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <fcntl.h> 
11 #include <sys/ioctl.h> 
12 #include <sys/stat.h> 
13 #include <sys/types.h> 
14 #include <unistd.h> 
15 #include <string.h>
16  
17 #include "v3_ctrl.h"
18
19 int read_file(int fd, int size, unsigned char * buf);
20
21 /* loop over the .dat/.img file that is in memory and look for the xml */
22 static int find_starting_point(unsigned char * buf) {
23     int i = 0;
24     for(;i<32;i++) {
25         if(*(buf+i) == '<') 
26             /* Looking for <vm class="PC"> portion of xml file. */
27             if(*(buf+i+1) == 'v')
28                 return i;
29     }
30     
31     return -1;
32 }
33
34 /* simple override option that just overwrites the characters in memory with
35    a new value. Supports string lengths of equal size or lesser size, but not
36    more than size. Kind of a rough hack to get it done, but should work for 
37    it's goal of changing mac addresses on the fly. */
38 int override_option(unsigned char * buf, char * option, char * value) {
39     int starting_point = find_starting_point(buf);
40     unsigned char * ptr;
41     unsigned char * end;
42     int i = 0;
43     
44     if(starting_point == -1) {
45         fprintf(stderr, "Could not find a starting point to make ");
46         fprintf(stderr, "modifications to the xml\n");
47         return -1;
48     }
49     
50     ptr = strstr(buf+starting_point, option);
51     /* essentially, return if the option isn't present */
52     if(ptr == NULL)
53         return -1;
54     
55     /* find end of xml tag */
56     ptr = strchr(buf+(ptr-buf), '>');
57     end = strchr(buf+(ptr-buf), '<');
58     
59     if(strlen(value) > (end-ptr-1)) {
60         fprintf(stderr, "Override option %s length is longer than currentlyin VM image file. This is not currently supported.\n", option);
61         return -1;
62     }
63     
64     for(i=0;i<strlen(value);i++) {
65         ptr[i+1] = value[i];
66     }
67     
68     /* the new option is smaller than the old one */
69     if(strlen(value) < (end-ptr-1)) {
70         int j = 0;
71         ptr[i+1] = '<';
72         i++;
73         ptr[i+1] = '/';
74         i++;
75         for(j;j<strlen(option);j++,i++) {
76             ptr[i+1] = option[j];
77         }
78         ptr[i+1] = '>';
79         i++;
80         for(j=0;j< (end-ptr-1)-strlen(value);j++,i++) {
81             ptr[i+1] = ' ';
82         }
83     }
84     
85     return 0;
86 }
87
88
89
90
91 int main(int argc, char* argv[]) {
92     char * filename = argv[1];
93     char * name = argv[2];
94     int guest_fd = 0;
95     int v3_fd = 0;
96     struct v3_guest_img guest_img;
97     struct stat guest_stats;
98     int dev_idx = 0;
99
100     memset(&guest_img, 0, sizeof(struct v3_guest_img));
101
102     if (argc <= 2) {
103         printf("usage: v3_create_bind <guest_img> <vm name> [override options]\n");
104         printf(" override options are of the form  KEY=VALUE\n");
105         return -1;
106     }
107
108     printf("Creating guest: %s\n", filename);
109
110     guest_fd = open(filename, O_RDONLY); 
111
112     if (guest_fd == -1) {
113         printf("Error Opening guest image: %s\n", filename);
114         return -1;
115     }
116
117     if (fstat(guest_fd, &guest_stats) == -1) {
118         printf("ERROR: Could not stat guest image file -- %s\n", filename);
119         return -1;
120     }
121
122     
123     guest_img.size = guest_stats.st_size;
124     
125     // load guest image into user memory
126     guest_img.guest_data = malloc(guest_img.size);
127
128     read_file(guest_fd, guest_img.size, guest_img.guest_data);
129     
130     close(guest_fd);
131
132     printf("Loaded guest image. Binding now.\n");
133
134     if(argc > 3) {
135         /* these are options. parse them and override the xml */
136         int i = 0;
137         for(i=3;i<argc;i++) {
138             char * argv_copy = malloc(strlen(argv[i]));
139             char * option;
140             char * value;
141             
142             strcpy(argv_copy, argv[i]);
143             option = strtok(argv_copy, "=");
144             value = strtok(NULL, "=");
145             
146             printf("Binding \"%s\" to \"%s\"\n",
147                    option, value);
148             override_option(guest_img.guest_data, option, value);
149             free(argv_copy);
150         }
151     }
152     
153     printf("Bound guest image.  Launching to V3Vee\n");
154     
155     strncpy(guest_img.name, name, 127);
156
157
158     v3_fd = open(v3_dev, O_RDONLY);
159
160     if (v3_fd == -1) {
161         printf("Error opening V3Vee control device\n");
162         return -1;
163     }
164
165     dev_idx = ioctl(v3_fd, V3_CREATE_GUEST, &guest_img); 
166
167
168     if (dev_idx < 0) {
169         printf("Error (%d) creating VM\n", dev_idx);
170         return -1;
171     }
172
173     printf("VM (%s) created at /dev/v3-vm%d\n", name, dev_idx);
174
175     /* Close the file descriptor.  */ 
176     close(v3_fd); 
177  
178
179
180     return 0; 
181
182
183
184
185 int read_file(int fd, int size, unsigned char * buf) {
186     int left_to_read = size;
187     int have_read = 0;
188
189     while (left_to_read != 0) {
190         int bytes_read = read(fd, buf + have_read, left_to_read);
191
192         if (bytes_read <= 0) {
193             break;
194         }
195
196         have_read += bytes_read;
197         left_to_read -= bytes_read;
198     }
199
200     if (left_to_read != 0) {
201         printf("Error could not finish reading file\n");
202         return -1;
203     }
204     
205     return 0;
206 }