]> rtime.felk.cvut.cz Git - jailhouse.git/blob - tools/jailhouse.c
driver/tools: Rework cell destruction API
[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 PRELOADIMAGE [-l ADDRESS]\n"
32                "   cell destroy CONFIGFILE\n",
33                progname);
34 }
35
36 static int open_dev()
37 {
38         int fd;
39
40         fd = open("/dev/jailhouse", O_RDWR);
41         if (fd < 0) {
42                 perror("opening /dev/jailhouse");
43                 exit(1);
44         }
45         return fd;
46 }
47
48 static void *read_file(const char *name, size_t *size)
49 {
50         struct stat stat;
51         void *buffer;
52         int fd;
53
54         fd = open(name, O_RDONLY);
55         if (fd < 0) {
56                 fprintf(stderr, "opening %s: %s\n", name, strerror(errno));
57                 exit(1);
58         }
59
60         if (fstat(fd, &stat) < 0) {
61                 perror("fstat");
62                 exit(1);
63         }
64
65         buffer = malloc(stat.st_size);
66         if (!buffer) {
67                 fprintf(stderr, "insufficient memory\n");
68                 exit(1);
69         }
70
71         if (read(fd, buffer, stat.st_size) < stat.st_size) {
72                 fprintf(stderr, "reading %s: %s\n", name, strerror(errno));
73                 exit(1);
74         }
75
76         close(fd);
77
78         if (size)
79                 *size = stat.st_size;
80
81         return buffer;
82 }
83
84 static int enable(int argc, char *argv[])
85 {
86         void *config;
87         int err, fd;
88
89         if (argc != 3) {
90                 help(argv[0]);
91                 exit(1);
92         }
93
94         config = read_file(argv[2], NULL);
95
96         fd = open_dev();
97
98         err = ioctl(fd, JAILHOUSE_ENABLE, config);
99         if (err)
100                 perror("JAILHOUSE_ENABLE");
101
102         close(fd);
103         free(config);
104
105         return err;
106 }
107
108 static int cell_create(int argc, char *argv[])
109 {
110         struct {
111                 struct jailhouse_new_cell cell;
112                 struct jailhouse_preload_image image;
113         } params;
114         struct jailhouse_new_cell *cell = &params.cell;
115         struct jailhouse_preload_image *image = params.cell.image;
116         size_t size;
117         int err, fd;
118         char *endp;
119
120         if (argc != 5 && argc != 7) {
121                 help(argv[0]);
122                 exit(1);
123         }
124
125         cell->config_address = (unsigned long)read_file(argv[3], &size);
126         cell->config_size = size;
127         cell->num_preload_images = 1;
128
129         image->source_address = (unsigned long)read_file(argv[4], &size);
130         image->size = size;
131         image->target_address = 0;
132
133         if (argc == 7) {
134                 errno = 0;
135                 image->target_address = strtoll(argv[6], &endp, 0);
136                 if (errno != 0 || *endp != 0 || strcmp(argv[5], "-l") != 0) {
137                         help(argv[0]);
138                         exit(1);
139                 }
140         }
141
142         fd = open_dev();
143
144         err = ioctl(fd, JAILHOUSE_CELL_CREATE, &params);
145         if (err)
146                 perror("JAILHOUSE_CELL_CREATE");
147
148         close(fd);
149         free((void *)(unsigned long)cell->config_address);
150         free((void *)(unsigned long)image->source_address);
151
152         return err;
153 }
154
155 static int cell_destroy(int argc, char *argv[])
156 {
157         struct jailhouse_cell cell;
158         size_t size;
159         int err, fd;
160
161         if (argc != 4) {
162                 help(argv[0]);
163                 exit(1);
164         }
165
166         cell.config_address = (unsigned long)read_file(argv[3], &size);
167         cell.config_size = size;
168
169         fd = open_dev();
170
171         err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell);
172         if (err)
173                 perror("JAILHOUSE_CELL_DESTROY");
174
175         close(fd);
176         free((void *)(unsigned long)cell.config_address);
177
178         return err;
179 }
180
181 static int cell_management(int argc, char *argv[])
182 {
183         int err;
184
185         if (argc < 3) {
186                 help(argv[0]);
187                 exit(1);
188         }
189
190         if (strcmp(argv[2], "create") == 0)
191                 err = cell_create(argc, argv);
192         else if (strcmp(argv[2], "destroy") == 0)
193                 err = cell_destroy(argc, argv);
194         else {
195                 help(argv[0]);
196                 exit(1);
197         }
198
199         return err;
200 }
201
202 int main(int argc, char *argv[])
203 {
204         int fd;
205         int err;
206
207         if (argc < 2) {
208                 help(argv[0]);
209                 exit(1);
210         }
211
212         if (strcmp(argv[1], "enable") == 0) {
213                 err = enable(argc, argv);
214         } else if (strcmp(argv[1], "disable") == 0) {
215                 fd = open_dev();
216                 err = ioctl(fd, JAILHOUSE_DISABLE);
217                 if (err)
218                         perror("JAILHOUSE_DISABLE");
219                 close(fd);
220         } else if (strcmp(argv[1], "cell") == 0) {
221                 err = cell_management(argc, argv);
222         } else {
223                 help(argv[0]);
224                 exit(1);
225         }
226
227         return err ? 1 : 0;
228 }