]> rtime.felk.cvut.cz Git - jailhouse.git/blob - tools/jailhouse.c
tools: Add support for loading multiple images during cell creation
[jailhouse.git] / tools / jailhouse.c
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2013
5  *
6  * Authors:
7  *  Jan Kiszka <jan.kiszka@siemens.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22
23 #include <jailhouse.h>
24
25 static void help(const char *progname)
26 {
27         printf("%s <command> <args>\n"
28                "\nAvailable commands:\n"
29                "   enable CONFIGFILE\n"
30                "   disable\n"
31                "   cell create CONFIGFILE IMAGE [-l ADDRESS] "
32                         "[IMAGE [-l ADDRESS] ...]\n"
33                "   cell destroy CONFIGFILE\n",
34                progname);
35 }
36
37 static int open_dev()
38 {
39         int fd;
40
41         fd = open("/dev/jailhouse", O_RDWR);
42         if (fd < 0) {
43                 perror("opening /dev/jailhouse");
44                 exit(1);
45         }
46         return fd;
47 }
48
49 static void *read_file(const char *name, size_t *size)
50 {
51         struct stat stat;
52         void *buffer;
53         int fd;
54
55         fd = open(name, O_RDONLY);
56         if (fd < 0) {
57                 fprintf(stderr, "opening %s: %s\n", name, strerror(errno));
58                 exit(1);
59         }
60
61         if (fstat(fd, &stat) < 0) {
62                 perror("fstat");
63                 exit(1);
64         }
65
66         buffer = malloc(stat.st_size);
67         if (!buffer) {
68                 fprintf(stderr, "insufficient memory\n");
69                 exit(1);
70         }
71
72         if (read(fd, buffer, stat.st_size) < stat.st_size) {
73                 fprintf(stderr, "reading %s: %s\n", name, strerror(errno));
74                 exit(1);
75         }
76
77         close(fd);
78
79         if (size)
80                 *size = stat.st_size;
81
82         return buffer;
83 }
84
85 static int enable(int argc, char *argv[])
86 {
87         void *config;
88         int err, fd;
89
90         if (argc != 3) {
91                 help(argv[0]);
92                 exit(1);
93         }
94
95         config = read_file(argv[2], NULL);
96
97         fd = open_dev();
98
99         err = ioctl(fd, JAILHOUSE_ENABLE, config);
100         if (err)
101                 perror("JAILHOUSE_ENABLE");
102
103         close(fd);
104         free(config);
105
106         return err;
107 }
108
109 static int cell_create(int argc, char *argv[])
110 {
111         struct jailhouse_preload_image *image;
112         struct jailhouse_new_cell *cell;
113         unsigned int images, arg_num;
114         size_t size;
115         int err, fd;
116         char *endp;
117
118         if (argc < 5) {
119                 help(argv[0]);
120                 exit(1);
121         }
122
123         arg_num = 4;
124         images = 0;
125         while (arg_num < argc) {
126                 images++;
127                 arg_num++;
128
129                 if (arg_num < argc && strcmp(argv[arg_num], "-l") == 0) {
130                         if (arg_num + 1 >= argc) {
131                                 help(argv[0]);
132                                 exit(1);
133                         }
134                         arg_num += 2;
135                 }
136         }
137
138         cell = malloc(sizeof(*cell) + sizeof(*image) * images);
139         if (!cell) {
140                 fprintf(stderr, "insufficient memory\n");
141                 exit(1);
142         }
143
144         cell->config_address = (unsigned long)read_file(argv[3], &size);
145         cell->config_size = size;
146         cell->num_preload_images = images;
147
148         arg_num = 4;
149         image = cell->image;
150
151         while (images > 0) {
152                 image->source_address =
153                         (unsigned long)read_file(argv[arg_num++], &size);
154                 image->size = size;
155                 image->target_address = 0;
156
157                 if (arg_num < argc && strcmp(argv[arg_num], "-l") == 0) {
158                         errno = 0;
159                         image->target_address =
160                                 strtoll(argv[arg_num + 1], &endp, 0);
161                         if (errno != 0 || *endp != 0) {
162                                 help(argv[0]);
163                                 exit(1);
164                         }
165                         arg_num += 2;
166                 }
167                 image++;
168                 images--;
169         }
170
171         fd = open_dev();
172
173         err = ioctl(fd, JAILHOUSE_CELL_CREATE, cell);
174         if (err)
175                 perror("JAILHOUSE_CELL_CREATE");
176
177         close(fd);
178         free((void *)(unsigned long)cell->config_address);
179         free((void *)(unsigned long)image->source_address);
180         free(cell);
181
182         return err;
183 }
184
185 static int cell_destroy(int argc, char *argv[])
186 {
187         struct jailhouse_cell cell;
188         size_t size;
189         int err, fd;
190
191         if (argc != 4) {
192                 help(argv[0]);
193                 exit(1);
194         }
195
196         cell.config_address = (unsigned long)read_file(argv[3], &size);
197         cell.config_size = size;
198
199         fd = open_dev();
200
201         err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell);
202         if (err)
203                 perror("JAILHOUSE_CELL_DESTROY");
204
205         close(fd);
206         free((void *)(unsigned long)cell.config_address);
207
208         return err;
209 }
210
211 static int cell_management(int argc, char *argv[])
212 {
213         int err;
214
215         if (argc < 3) {
216                 help(argv[0]);
217                 exit(1);
218         }
219
220         if (strcmp(argv[2], "create") == 0)
221                 err = cell_create(argc, argv);
222         else if (strcmp(argv[2], "destroy") == 0)
223                 err = cell_destroy(argc, argv);
224         else {
225                 help(argv[0]);
226                 exit(1);
227         }
228
229         return err;
230 }
231
232 int main(int argc, char *argv[])
233 {
234         int fd;
235         int err;
236
237         if (argc < 2) {
238                 help(argv[0]);
239                 exit(1);
240         }
241
242         if (strcmp(argv[1], "enable") == 0) {
243                 err = enable(argc, argv);
244         } else if (strcmp(argv[1], "disable") == 0) {
245                 fd = open_dev();
246                 err = ioctl(fd, JAILHOUSE_DISABLE);
247                 if (err)
248                         perror("JAILHOUSE_DISABLE");
249                 close(fd);
250         } else if (strcmp(argv[1], "cell") == 0) {
251                 err = cell_management(argc, argv);
252         } else {
253                 help(argv[0]);
254                 exit(1);
255         }
256
257         return err ? 1 : 0;
258 }