2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2013
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
20 #include <sys/types.h>
21 #include <sys/ioctl.h>
24 #include <jailhouse.h>
26 static void __attribute__((noreturn))
27 help(const char *progname, int exit_status)
29 printf("%s { COMMAND | --help }\n"
30 "\nAvailable commands:\n"
33 " cell create CELLCONFIG\n"
34 " cell load { ID | [--name] NAME } IMAGE "
35 "[ -a | --address ADDRESS] ...\n"
36 " cell start { ID | [--name] NAME }\n"
37 " cell destroy { ID | [--name] NAME }\n",
46 fd = open("/dev/jailhouse", O_RDWR);
48 perror("opening /dev/jailhouse");
54 static void *read_file(const char *name, size_t *size)
60 fd = open(name, O_RDONLY);
62 fprintf(stderr, "opening %s: %s\n", name, strerror(errno));
66 if (fstat(fd, &stat) < 0) {
71 buffer = malloc(stat.st_size);
73 fprintf(stderr, "insufficient memory\n");
77 if (read(fd, buffer, stat.st_size) < stat.st_size) {
78 fprintf(stderr, "reading %s: %s\n", name, strerror(errno));
90 static int enable(int argc, char *argv[])
98 config = read_file(argv[2], NULL);
102 err = ioctl(fd, JAILHOUSE_ENABLE, config);
104 perror("JAILHOUSE_ENABLE");
112 static int cell_create(int argc, char *argv[])
114 struct jailhouse_cell_create cell_create;
121 cell_create.config_address = (unsigned long)read_file(argv[3], &size);
122 cell_create.config_size = size;
126 err = ioctl(fd, JAILHOUSE_CELL_CREATE, &cell_create);
128 perror("JAILHOUSE_CELL_CREATE");
135 static int parse_cell_id(struct jailhouse_cell_id *cell_id, int argc,
138 bool use_name = false;
145 if (strcmp(argv[0], "--name") == 0) {
152 cell_id->id = strtoll(argv[0], &endp, 0);
153 if (errno != 0 || *endp != 0 || cell_id->id < 0)
158 cell_id->id = JAILHOUSE_CELL_ID_UNUSED;
159 strncpy(cell_id->name, argv[arg_pos], sizeof(cell_id->name));
160 cell_id->name[sizeof(cell_id->name) - 1] = 0;
166 static bool match_opt(const char *argv, const char *short_opt,
167 const char *long_opt)
169 return strcmp(argv, short_opt) == 0 ||
170 strcmp(argv, long_opt) == 0;
173 static int cell_load(int argc, char *argv[])
175 unsigned int images, id_args, arg_num, n;
176 struct jailhouse_preload_image *image;
177 struct jailhouse_cell_load *cell_load;
178 struct jailhouse_cell_id cell_id;
183 id_args = parse_cell_id(&cell_id, argc - 3, &argv[3]);
184 arg_num = 3 + id_args;
185 if (id_args == 0 || arg_num == argc)
189 while (arg_num < argc) {
193 if (arg_num < argc &&
194 match_opt(argv[arg_num], "-a", "--address")) {
195 if (arg_num + 1 >= argc)
201 cell_load = malloc(sizeof(*cell_load) + sizeof(*image) * images);
203 fprintf(stderr, "insufficient memory\n");
206 cell_load->cell_id = cell_id;
207 cell_load->num_preload_images = images;
209 arg_num = 3 + id_args;
211 for (n = 0, image = cell_load->image; n < images; n++, image++) {
212 image->source_address =
213 (unsigned long)read_file(argv[arg_num++], &size);
215 image->target_address = 0;
217 if (arg_num < argc &&
218 match_opt(argv[arg_num], "-a", "--address")) {
220 image->target_address =
221 strtoll(argv[arg_num + 1], &endp, 0);
222 if (errno != 0 || *endp != 0)
231 err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load);
233 perror("JAILHOUSE_CELL_LOAD");
236 for (n = 0, image = cell_load->image; n < images; n++, image++)
237 free((void *)(unsigned long)image->source_address);
243 static int cell_simple_cmd(int argc, char *argv[], unsigned int command)
245 struct jailhouse_cell_id cell_id;
246 int id_args, err, fd;
248 id_args = parse_cell_id(&cell_id, argc - 3, &argv[3]);
249 if (id_args == 0 || 3 + id_args != argc)
254 err = ioctl(fd, command, &cell_id);
256 perror(command == JAILHOUSE_CELL_START ?
257 "JAILHOUSE_CELL_START" :
258 command == JAILHOUSE_CELL_DESTROY ?
259 "JAILHOUSE_CELL_DESTROY" :
260 "<unknown command>");
267 static int cell_management(int argc, char *argv[])
274 if (strcmp(argv[2], "create") == 0)
275 err = cell_create(argc, argv);
276 else if (strcmp(argv[2], "load") == 0)
277 err = cell_load(argc, argv);
278 else if (strcmp(argv[2], "start") == 0)
279 err = cell_simple_cmd(argc, argv, JAILHOUSE_CELL_START);
280 else if (strcmp(argv[2], "destroy") == 0)
281 err = cell_simple_cmd(argc, argv, JAILHOUSE_CELL_DESTROY);
288 int main(int argc, char *argv[])
296 if (strcmp(argv[1], "enable") == 0) {
297 err = enable(argc, argv);
298 } else if (strcmp(argv[1], "disable") == 0) {
300 err = ioctl(fd, JAILHOUSE_DISABLE);
302 perror("JAILHOUSE_DISABLE");
304 } else if (strcmp(argv[1], "cell") == 0) {
305 err = cell_management(argc, argv);
306 } else if (strcmp(argv[1], "--help") == 0) {