These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / hci / commands / image_cmd.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <getopt.h>
31 #include <ipxe/image.h>
32 #include <ipxe/command.h>
33 #include <ipxe/parseopt.h>
34 #include <ipxe/shell.h>
35 #include <usr/imgmgmt.h>
36
37 /** @file
38  *
39  * Image management commands
40  *
41  */
42
43 /** "img{single}" options */
44 struct imgsingle_options {
45         /** Image name */
46         char *name;
47         /** Download timeout */
48         unsigned long timeout;
49         /** Replace image */
50         int replace;
51         /** Free image after execution */
52         int autofree;
53 };
54
55 /** "img{single}" option list */
56 static union {
57         /* "imgexec" takes all three options */
58         struct option_descriptor imgexec[4];
59         /* Other "img{single}" commands take only --name, --timeout,
60          * and --autofree
61          */
62         struct option_descriptor imgsingle[3];
63 } opts = {
64         .imgexec = {
65                 OPTION_DESC ( "name", 'n', required_argument,
66                               struct imgsingle_options, name, parse_string ),
67                 OPTION_DESC ( "timeout", 't', required_argument,
68                               struct imgsingle_options, timeout, parse_timeout),
69                 OPTION_DESC ( "autofree", 'a', no_argument,
70                               struct imgsingle_options, autofree, parse_flag ),
71                 OPTION_DESC ( "replace", 'r', no_argument,
72                               struct imgsingle_options, replace, parse_flag ),
73         },
74 };
75
76 /** An "img{single}" family command descriptor */
77 struct imgsingle_descriptor {
78         /** Command descriptor */
79         struct command_descriptor *cmd;
80         /** Function to use to acquire the image */
81         int ( * acquire ) ( const char *name, unsigned long timeout,
82                             struct image **image );
83         /** Pre-action to take upon image, or NULL */
84         void ( * preaction ) ( struct image *image );
85         /** Action to take upon image, or NULL */
86         int ( * action ) ( struct image *image,
87                            struct imgsingle_options *opts );
88         /** Verb to describe action */
89         const char *verb;
90 };
91
92 /**
93  * The "img{single}" family of commands
94  *
95  * @v argc              Argument count
96  * @v argv              Argument list
97  * @v desc              "img{single}" command descriptor
98  * @v action_name       Action name (for error messages)
99  * @v action            Action to take upon image
100  * @ret rc              Return status code
101  */
102 static int imgsingle_exec ( int argc, char **argv,
103                             struct imgsingle_descriptor *desc ) {
104         struct imgsingle_options opts;
105         char *name_uri = NULL;
106         char *cmdline = NULL;
107         struct image *image;
108         int rc;
109
110         /* Parse options */
111         if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
112                 goto err_parse_options;
113
114         /* Parse name/URI string and command line, if present */
115         if ( optind < argc ) {
116                 name_uri = argv[optind];
117                 if ( argv[ optind + 1 ] != NULL ) {
118                         cmdline = concat_args ( &argv[ optind + 1 ] );
119                         if ( ! cmdline ) {
120                                 rc = -ENOMEM;
121                                 goto err_parse_cmdline;
122                         }
123                 }
124         }
125
126         /* Acquire the image */
127         if ( name_uri ) {
128                 if ( ( rc = desc->acquire ( name_uri, opts.timeout,
129                                             &image ) ) != 0 )
130                         goto err_acquire;
131         } else {
132                 image = image_find_selected();
133                 if ( ! image ) {
134                         printf ( "No image selected\n" );
135                         goto err_acquire;
136                 }
137         }
138
139         /* Carry out command pre-action, if applicable */
140         if ( desc->preaction )
141                 desc->preaction ( image );
142
143         /* Set the image name, if applicable */
144         if ( opts.name ) {
145                 if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
146                         printf ( "Could not name image: %s\n",
147                                  strerror ( rc ) );
148                         goto err_set_name;
149                 }
150         }
151
152         /* Set the command-line arguments, if applicable */
153         if ( cmdline ) {
154                 if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
155                         printf ( "Could not set arguments: %s\n",
156                                  strerror ( rc ) );
157                         goto err_set_cmdline;
158                 }
159         }
160
161         /* Set the auto-unregister flag, if applicable */
162         if ( opts.autofree )
163                 image->flags |= IMAGE_AUTO_UNREGISTER;
164
165         /* Carry out command action, if applicable */
166         if ( desc->action ) {
167                 if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
168                         printf ( "Could not %s: %s\n",
169                                  desc->verb, strerror ( rc ) );
170                         goto err_action;
171                 }
172         }
173
174         /* Success */
175         rc = 0;
176
177  err_action:
178  err_set_cmdline:
179  err_set_name:
180  err_acquire:
181         free ( cmdline );
182  err_parse_cmdline:
183  err_parse_options:
184         return rc;
185 }
186
187 /** "imgfetch" command descriptor */
188 static struct command_descriptor imgfetch_cmd =
189         COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
190                        1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
191
192 /** "imgfetch" family command descriptor */
193 struct imgsingle_descriptor imgfetch_desc = {
194         .cmd = &imgfetch_cmd,
195         .acquire = imgdownload_string,
196 };
197
198 /**
199  * The "imgfetch" command
200  *
201  * @v argc              Argument count
202  * @v argv              Argument list
203  * @ret rc              Return status code
204  */
205 static int imgfetch_exec ( int argc, char **argv ) {
206         return imgsingle_exec ( argc, argv, &imgfetch_desc );
207 }
208
209 /**
210  * "imgselect" command action
211  *
212  * @v image             Image
213  * @v opts              Options
214  * @ret rc              Return status code
215  */
216 static int imgselect ( struct image *image,
217                        struct imgsingle_options *opts __unused ) {
218         return image_select ( image );
219 }
220
221 /** "imgselect" command descriptor */
222 static struct command_descriptor imgselect_cmd =
223         COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
224                        1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
225
226 /** "imgselect" family command descriptor */
227 struct imgsingle_descriptor imgselect_desc = {
228         .cmd = &imgselect_cmd,
229         .acquire = imgacquire,
230         .action = imgselect,
231         .verb = "select",
232 };
233
234 /**
235  * The "imgselect" command
236  *
237  * @v argc              Argument count
238  * @v argv              Argument list
239  * @ret rc              Return status code
240  */
241 static int imgselect_exec ( int argc, char **argv ) {
242         return imgsingle_exec ( argc, argv, &imgselect_desc );
243 }
244
245 /** "imgexec" command descriptor */
246 static struct command_descriptor imgexec_cmd =
247         COMMAND_DESC ( struct imgsingle_options, opts.imgexec,
248                        0, MAX_ARGUMENTS, "[<uri|image> [<arguments>...]]" );
249
250 /**
251  * "imgexec" command action
252  *
253  * @v image             Image
254  * @v opts              Options
255  * @ret rc              Return status code
256  */
257 static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
258         int rc;
259
260         /* Perform replacement or execution as applicable */
261         if ( opts->replace ) {
262
263                 /* Try to replace image */
264                 if ( ( rc = image_replace ( image ) ) != 0 )
265                         return rc;
266
267                 /* Stop script and tail-recurse into replacement image */
268                 shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
269
270         } else {
271
272                 /* Try to execute image */
273                 if ( ( rc = image_exec ( image ) ) != 0 )
274                         return rc;
275         }
276
277         return 0;
278 }
279
280 /** "imgexec" family command descriptor */
281 struct imgsingle_descriptor imgexec_desc = {
282         .cmd = &imgexec_cmd,
283         .acquire = imgacquire,
284         .action = imgexec,
285         .verb = "boot",
286 };
287
288 /**
289  * The "imgexec" command
290  *
291  * @v argc              Argument count
292  * @v argv              Argument list
293  * @ret rc              Return status code
294  */
295 static int imgexec_exec ( int argc, char **argv) {
296         return imgsingle_exec ( argc, argv, &imgexec_desc );
297 }
298
299 /** "imgargs" command descriptor */
300 static struct command_descriptor imgargs_cmd =
301         COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
302                        1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
303
304 /** "imgargs" family command descriptor */
305 struct imgsingle_descriptor imgargs_desc = {
306         .cmd = &imgargs_cmd,
307         .acquire = imgacquire,
308         .preaction = image_clear_cmdline,
309 };
310
311 /**
312  * The "imgargs" command body
313  *
314  * @v argc              Argument count
315  * @v argv              Argument list
316  * @ret rc              Return status code
317  */
318 static int imgargs_exec ( int argc, char **argv ) {
319         return imgsingle_exec ( argc, argv, &imgargs_desc );
320 }
321
322 /** "img{multi}" options */
323 struct imgmulti_options {};
324
325 /** "img{multi}" option list */
326 static struct option_descriptor imgmulti_opts[] = {};
327
328 /** "img{multi}" command descriptor */
329 static struct command_descriptor imgmulti_cmd =
330         COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
331                        "[<image>...]" );
332
333 /**
334  * The "img{multi}" family of commands
335  *
336  * @v argc              Argument count
337  * @v argv              Argument list
338  * @v payload           Function to execute on each image
339  * @ret rc              Return status code
340  */
341 static int imgmulti_exec ( int argc, char **argv,
342                            void ( * payload ) ( struct image *image ) ) {
343         struct imgmulti_options opts;
344         struct image *image;
345         struct image *tmp;
346         int i;
347         int rc;
348
349         /* Parse options */
350         if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
351                 return rc;
352
353         /* If no images are explicitly specified, process all images */
354         if ( optind == argc ) {
355                 for_each_image_safe ( image, tmp )
356                         payload ( image );
357                 return 0;
358         }
359
360         /* Otherwise, process specified images */
361         for ( i = optind ; i < argc ; i++ ) {
362                 image = find_image ( argv[i] );
363                 if ( ! image ) {
364                         printf ( "\"%s\": no such image\n", argv[i] );
365                         return -ENOENT;
366                 }
367                 payload ( image );
368         }
369
370         return 0;
371 }
372
373 /**
374  * The "imgstat" command
375  *
376  * @v argc              Argument count
377  * @v argv              Argument list
378  * @ret rc              Return status code
379  */
380 static int imgstat_exec ( int argc, char **argv ) {
381         return imgmulti_exec ( argc, argv, imgstat );
382 }
383
384 /**
385  * The "imgfree" command
386  *
387  * @v argc              Argument count
388  * @v argv              Argument list
389  * @ret rc              Return status code
390  */
391 static int imgfree_exec ( int argc, char **argv ) {
392         return imgmulti_exec ( argc, argv, unregister_image );
393 }
394
395 /** Image management commands */
396 struct command image_commands[] __command = {
397         {
398                 .name = "imgfetch",
399                 .exec = imgfetch_exec,
400         },
401         {
402                 .name = "module",
403                 .exec = imgfetch_exec, /* synonym for "imgfetch" */
404         },
405         {
406                 .name = "initrd",
407                 .exec = imgfetch_exec, /* synonym for "imgfetch" */
408         },
409         {
410                 .name = "kernel",
411                 .exec = imgselect_exec, /* synonym for "imgselect" */
412         },
413         {
414                 .name = "chain",
415                 .exec = imgexec_exec, /* synonym for "imgexec" */
416         },
417         {
418                 .name = "imgselect",
419                 .exec = imgselect_exec,
420         },
421         {
422                 .name = "imgload",
423                 .exec = imgselect_exec, /* synonym for "imgselect" */
424         },
425         {
426                 .name = "imgargs",
427                 .exec = imgargs_exec,
428         },
429         {
430                 .name = "imgexec",
431                 .exec = imgexec_exec,
432         },
433         {
434                 .name = "boot", /* synonym for "imgexec" */
435                 .exec = imgexec_exec,
436         },
437         {
438                 .name = "imgstat",
439                 .exec = imgstat_exec,
440         },
441         {
442                 .name = "imgfree",
443                 .exec = imgfree_exec,
444         },
445 };