X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fipxe%2Fsrc%2Fhci%2Fcommands%2Fimage_cmd.c;fp=qemu%2Froms%2Fipxe%2Fsrc%2Fhci%2Fcommands%2Fimage_cmd.c;h=a9e831bf507c1e0aad186b8c211a472885a12f9a;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/ipxe/src/hci/commands/image_cmd.c b/qemu/roms/ipxe/src/hci/commands/image_cmd.c new file mode 100644 index 000000000..a9e831bf5 --- /dev/null +++ b/qemu/roms/ipxe/src/hci/commands/image_cmd.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2007 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** @file + * + * Image management commands + * + */ + +/** "img{single}" options */ +struct imgsingle_options { + /** Image name */ + char *name; + /** Download timeout */ + unsigned long timeout; + /** Replace image */ + int replace; + /** Free image after execution */ + int autofree; +}; + +/** "img{single}" option list */ +static union { + /* "imgexec" takes all three options */ + struct option_descriptor imgexec[4]; + /* Other "img{single}" commands take only --name, --timeout, + * and --autofree + */ + struct option_descriptor imgsingle[3]; +} opts = { + .imgexec = { + OPTION_DESC ( "name", 'n', required_argument, + struct imgsingle_options, name, parse_string ), + OPTION_DESC ( "timeout", 't', required_argument, + struct imgsingle_options, timeout, parse_timeout), + OPTION_DESC ( "autofree", 'a', no_argument, + struct imgsingle_options, autofree, parse_flag ), + OPTION_DESC ( "replace", 'r', no_argument, + struct imgsingle_options, replace, parse_flag ), + }, +}; + +/** An "img{single}" family command descriptor */ +struct imgsingle_descriptor { + /** Command descriptor */ + struct command_descriptor *cmd; + /** Function to use to acquire the image */ + int ( * acquire ) ( const char *name, unsigned long timeout, + struct image **image ); + /** Pre-action to take upon image, or NULL */ + void ( * preaction ) ( struct image *image ); + /** Action to take upon image, or NULL */ + int ( * action ) ( struct image *image, + struct imgsingle_options *opts ); + /** Verb to describe action */ + const char *verb; +}; + +/** + * The "img{single}" family of commands + * + * @v argc Argument count + * @v argv Argument list + * @v desc "img{single}" command descriptor + * @v action_name Action name (for error messages) + * @v action Action to take upon image + * @ret rc Return status code + */ +static int imgsingle_exec ( int argc, char **argv, + struct imgsingle_descriptor *desc ) { + struct imgsingle_options opts; + char *name_uri = NULL; + char *cmdline = NULL; + struct image *image; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 ) + goto err_parse_options; + + /* Parse name/URI string and command line, if present */ + if ( optind < argc ) { + name_uri = argv[optind]; + if ( argv[ optind + 1 ] != NULL ) { + cmdline = concat_args ( &argv[ optind + 1 ] ); + if ( ! cmdline ) { + rc = -ENOMEM; + goto err_parse_cmdline; + } + } + } + + /* Acquire the image */ + if ( name_uri ) { + if ( ( rc = desc->acquire ( name_uri, opts.timeout, + &image ) ) != 0 ) + goto err_acquire; + } else { + image = image_find_selected(); + if ( ! image ) { + printf ( "No image selected\n" ); + goto err_acquire; + } + } + + /* Carry out command pre-action, if applicable */ + if ( desc->preaction ) + desc->preaction ( image ); + + /* Set the image name, if applicable */ + if ( opts.name ) { + if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) { + printf ( "Could not name image: %s\n", + strerror ( rc ) ); + goto err_set_name; + } + } + + /* Set the command-line arguments, if applicable */ + if ( cmdline ) { + if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) { + printf ( "Could not set arguments: %s\n", + strerror ( rc ) ); + goto err_set_cmdline; + } + } + + /* Set the auto-unregister flag, if applicable */ + if ( opts.autofree ) + image->flags |= IMAGE_AUTO_UNREGISTER; + + /* Carry out command action, if applicable */ + if ( desc->action ) { + if ( ( rc = desc->action ( image, &opts ) ) != 0 ) { + printf ( "Could not %s: %s\n", + desc->verb, strerror ( rc ) ); + goto err_action; + } + } + + /* Success */ + rc = 0; + + err_action: + err_set_cmdline: + err_set_name: + err_acquire: + free ( cmdline ); + err_parse_cmdline: + err_parse_options: + return rc; +} + +/** "imgfetch" command descriptor */ +static struct command_descriptor imgfetch_cmd = + COMMAND_DESC ( struct imgsingle_options, opts.imgsingle, + 1, MAX_ARGUMENTS, " [...]" ); + +/** "imgfetch" family command descriptor */ +struct imgsingle_descriptor imgfetch_desc = { + .cmd = &imgfetch_cmd, + .acquire = imgdownload_string, +}; + +/** + * The "imgfetch" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgfetch_exec ( int argc, char **argv ) { + return imgsingle_exec ( argc, argv, &imgfetch_desc ); +} + +/** + * "imgselect" command action + * + * @v image Image + * @v opts Options + * @ret rc Return status code + */ +static int imgselect ( struct image *image, + struct imgsingle_options *opts __unused ) { + return image_select ( image ); +} + +/** "imgselect" command descriptor */ +static struct command_descriptor imgselect_cmd = + COMMAND_DESC ( struct imgsingle_options, opts.imgsingle, + 1, MAX_ARGUMENTS, " [...]" ); + +/** "imgselect" family command descriptor */ +struct imgsingle_descriptor imgselect_desc = { + .cmd = &imgselect_cmd, + .acquire = imgacquire, + .action = imgselect, + .verb = "select", +}; + +/** + * The "imgselect" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgselect_exec ( int argc, char **argv ) { + return imgsingle_exec ( argc, argv, &imgselect_desc ); +} + +/** "imgexec" command descriptor */ +static struct command_descriptor imgexec_cmd = + COMMAND_DESC ( struct imgsingle_options, opts.imgexec, + 0, MAX_ARGUMENTS, "[ [...]]" ); + +/** + * "imgexec" command action + * + * @v image Image + * @v opts Options + * @ret rc Return status code + */ +static int imgexec ( struct image *image, struct imgsingle_options *opts ) { + int rc; + + /* Perform replacement or execution as applicable */ + if ( opts->replace ) { + + /* Try to replace image */ + if ( ( rc = image_replace ( image ) ) != 0 ) + return rc; + + /* Stop script and tail-recurse into replacement image */ + shell_stop ( SHELL_STOP_COMMAND_SEQUENCE ); + + } else { + + /* Try to execute image */ + if ( ( rc = image_exec ( image ) ) != 0 ) + return rc; + } + + return 0; +} + +/** "imgexec" family command descriptor */ +struct imgsingle_descriptor imgexec_desc = { + .cmd = &imgexec_cmd, + .acquire = imgacquire, + .action = imgexec, + .verb = "boot", +}; + +/** + * The "imgexec" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgexec_exec ( int argc, char **argv) { + return imgsingle_exec ( argc, argv, &imgexec_desc ); +} + +/** "imgargs" command descriptor */ +static struct command_descriptor imgargs_cmd = + COMMAND_DESC ( struct imgsingle_options, opts.imgsingle, + 1, MAX_ARGUMENTS, " [...]" ); + +/** "imgargs" family command descriptor */ +struct imgsingle_descriptor imgargs_desc = { + .cmd = &imgargs_cmd, + .acquire = imgacquire, + .preaction = image_clear_cmdline, +}; + +/** + * The "imgargs" command body + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgargs_exec ( int argc, char **argv ) { + return imgsingle_exec ( argc, argv, &imgargs_desc ); +} + +/** "img{multi}" options */ +struct imgmulti_options {}; + +/** "img{multi}" option list */ +static struct option_descriptor imgmulti_opts[] = {}; + +/** "img{multi}" command descriptor */ +static struct command_descriptor imgmulti_cmd = + COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS, + "[...]" ); + +/** + * The "img{multi}" family of commands + * + * @v argc Argument count + * @v argv Argument list + * @v payload Function to execute on each image + * @ret rc Return status code + */ +static int imgmulti_exec ( int argc, char **argv, + void ( * payload ) ( struct image *image ) ) { + struct imgmulti_options opts; + struct image *image; + struct image *tmp; + int i; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 ) + return rc; + + /* If no images are explicitly specified, process all images */ + if ( optind == argc ) { + for_each_image_safe ( image, tmp ) + payload ( image ); + return 0; + } + + /* Otherwise, process specified images */ + for ( i = optind ; i < argc ; i++ ) { + image = find_image ( argv[i] ); + if ( ! image ) { + printf ( "\"%s\": no such image\n", argv[i] ); + return -ENOENT; + } + payload ( image ); + } + + return 0; +} + +/** + * The "imgstat" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgstat_exec ( int argc, char **argv ) { + return imgmulti_exec ( argc, argv, imgstat ); +} + +/** + * The "imgfree" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgfree_exec ( int argc, char **argv ) { + return imgmulti_exec ( argc, argv, unregister_image ); +} + +/** Image management commands */ +struct command image_commands[] __command = { + { + .name = "imgfetch", + .exec = imgfetch_exec, + }, + { + .name = "module", + .exec = imgfetch_exec, /* synonym for "imgfetch" */ + }, + { + .name = "initrd", + .exec = imgfetch_exec, /* synonym for "imgfetch" */ + }, + { + .name = "kernel", + .exec = imgselect_exec, /* synonym for "imgselect" */ + }, + { + .name = "chain", + .exec = imgexec_exec, /* synonym for "imgexec" */ + }, + { + .name = "imgselect", + .exec = imgselect_exec, + }, + { + .name = "imgload", + .exec = imgselect_exec, /* synonym for "imgselect" */ + }, + { + .name = "imgargs", + .exec = imgargs_exec, + }, + { + .name = "imgexec", + .exec = imgexec_exec, + }, + { + .name = "boot", /* synonym for "imgexec" */ + .exec = imgexec_exec, + }, + { + .name = "imgstat", + .exec = imgstat_exec, + }, + { + .name = "imgfree", + .exec = imgfree_exec, + }, +};