You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

image_cmd.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <stdint.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <getopt.h>
  25. #include <ipxe/image.h>
  26. #include <ipxe/command.h>
  27. #include <ipxe/parseopt.h>
  28. #include <ipxe/shell.h>
  29. #include <usr/imgmgmt.h>
  30. /** @file
  31. *
  32. * Image management commands
  33. *
  34. */
  35. /** "img{single}" options */
  36. struct imgsingle_options {
  37. /** Image name */
  38. char *name;
  39. /** Replace image */
  40. int replace;
  41. /** Free image after execution */
  42. int autofree;
  43. };
  44. /** "img{single}" option list */
  45. static union {
  46. /* "imgexec" takes all three options */
  47. struct option_descriptor imgexec[3];
  48. /* Other "img{single}" commands take only --name and --autofree */
  49. struct option_descriptor imgsingle[2];
  50. } opts = {
  51. .imgexec = {
  52. OPTION_DESC ( "name", 'n', required_argument,
  53. struct imgsingle_options, name, parse_string ),
  54. OPTION_DESC ( "autofree", 'a', no_argument,
  55. struct imgsingle_options, autofree, parse_flag ),
  56. OPTION_DESC ( "replace", 'r', no_argument,
  57. struct imgsingle_options, replace, parse_flag ),
  58. },
  59. };
  60. /** An "img{single}" family command descriptor */
  61. struct imgsingle_descriptor {
  62. /** Command descriptor */
  63. struct command_descriptor *cmd;
  64. /** Function to use to acquire the image */
  65. int ( * acquire ) ( const char *name, struct image **image );
  66. /** Pre-action to take upon image, or NULL */
  67. void ( * preaction ) ( struct image *image );
  68. /** Action to take upon image, or NULL */
  69. int ( * action ) ( struct image *image,
  70. struct imgsingle_options *opts );
  71. /** Verb to describe action */
  72. const char *verb;
  73. };
  74. /**
  75. * The "img{single}" family of commands
  76. *
  77. * @v argc Argument count
  78. * @v argv Argument list
  79. * @v desc "img{single}" command descriptor
  80. * @v action_name Action name (for error messages)
  81. * @v action Action to take upon image
  82. * @ret rc Return status code
  83. */
  84. static int imgsingle_exec ( int argc, char **argv,
  85. struct imgsingle_descriptor *desc ) {
  86. struct imgsingle_options opts;
  87. char *name_uri = NULL;
  88. char *cmdline = NULL;
  89. struct image *image;
  90. int rc;
  91. /* Parse options */
  92. if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
  93. goto err_parse_options;
  94. /* Parse name/URI string and command line, if present */
  95. if ( optind < argc ) {
  96. name_uri = argv[optind];
  97. if ( argv[ optind + 1 ] != NULL ) {
  98. cmdline = concat_args ( &argv[ optind + 1 ] );
  99. if ( ! cmdline ) {
  100. rc = -ENOMEM;
  101. goto err_parse_cmdline;
  102. }
  103. }
  104. }
  105. /* Acquire the image */
  106. if ( name_uri ) {
  107. if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
  108. goto err_acquire;
  109. } else {
  110. image = image_find_selected();
  111. if ( ! image ) {
  112. printf ( "No image selected\n" );
  113. goto err_acquire;
  114. }
  115. }
  116. /* Carry out command pre-action, if applicable */
  117. if ( desc->preaction )
  118. desc->preaction ( image );
  119. /* Set the image name, if applicable */
  120. if ( opts.name ) {
  121. if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
  122. printf ( "Could not name image: %s\n",
  123. strerror ( rc ) );
  124. goto err_set_name;
  125. }
  126. }
  127. /* Set the command-line arguments, if applicable */
  128. if ( cmdline ) {
  129. if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
  130. printf ( "Could not set arguments: %s\n",
  131. strerror ( rc ) );
  132. goto err_set_cmdline;
  133. }
  134. }
  135. /* Set the auto-unregister flag, if applicable */
  136. if ( opts.autofree )
  137. image->flags |= IMAGE_AUTO_UNREGISTER;
  138. /* Carry out command action, if applicable */
  139. if ( desc->action ) {
  140. if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
  141. printf ( "Could not %s: %s\n",
  142. desc->verb, strerror ( rc ) );
  143. goto err_action;
  144. }
  145. }
  146. /* Success */
  147. rc = 0;
  148. err_action:
  149. err_set_cmdline:
  150. err_set_name:
  151. err_acquire:
  152. free ( cmdline );
  153. err_parse_cmdline:
  154. err_parse_options:
  155. return rc;
  156. }
  157. /** "imgfetch" command descriptor */
  158. static struct command_descriptor imgfetch_cmd =
  159. COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
  160. 1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
  161. /** "imgfetch" family command descriptor */
  162. struct imgsingle_descriptor imgfetch_desc = {
  163. .cmd = &imgfetch_cmd,
  164. .acquire = imgdownload_string,
  165. };
  166. /**
  167. * The "imgfetch" command
  168. *
  169. * @v argc Argument count
  170. * @v argv Argument list
  171. * @ret rc Return status code
  172. */
  173. static int imgfetch_exec ( int argc, char **argv ) {
  174. return imgsingle_exec ( argc, argv, &imgfetch_desc );
  175. }
  176. /**
  177. * "imgselect" command action
  178. *
  179. * @v image Image
  180. * @v opts Options
  181. * @ret rc Return status code
  182. */
  183. static int imgselect ( struct image *image,
  184. struct imgsingle_options *opts __unused ) {
  185. return image_select ( image );
  186. }
  187. /** "imgselect" command descriptor */
  188. static struct command_descriptor imgselect_cmd =
  189. COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
  190. 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
  191. /** "imgselect" family command descriptor */
  192. struct imgsingle_descriptor imgselect_desc = {
  193. .cmd = &imgselect_cmd,
  194. .acquire = imgacquire,
  195. .action = imgselect,
  196. .verb = "select",
  197. };
  198. /**
  199. * The "imgselect" command
  200. *
  201. * @v argc Argument count
  202. * @v argv Argument list
  203. * @ret rc Return status code
  204. */
  205. static int imgselect_exec ( int argc, char **argv ) {
  206. return imgsingle_exec ( argc, argv, &imgselect_desc );
  207. }
  208. /** "imgexec" command descriptor */
  209. static struct command_descriptor imgexec_cmd =
  210. COMMAND_DESC ( struct imgsingle_options, opts.imgexec,
  211. 0, MAX_ARGUMENTS, "[<uri|image> [<arguments>...]]" );
  212. /**
  213. * "imgexec" command action
  214. *
  215. * @v image Image
  216. * @v opts Options
  217. * @ret rc Return status code
  218. */
  219. static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
  220. int rc;
  221. /* Perform replacement or execution as applicable */
  222. if ( opts->replace ) {
  223. /* Try to replace image */
  224. if ( ( rc = image_replace ( image ) ) != 0 )
  225. return rc;
  226. /* Stop script and tail-recurse into replacement image */
  227. shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
  228. } else {
  229. /* Try to execute image */
  230. if ( ( rc = image_exec ( image ) ) != 0 )
  231. return rc;
  232. }
  233. return 0;
  234. }
  235. /** "imgexec" family command descriptor */
  236. struct imgsingle_descriptor imgexec_desc = {
  237. .cmd = &imgexec_cmd,
  238. .acquire = imgacquire,
  239. .action = imgexec,
  240. .verb = "boot",
  241. };
  242. /**
  243. * The "imgexec" command
  244. *
  245. * @v argc Argument count
  246. * @v argv Argument list
  247. * @ret rc Return status code
  248. */
  249. static int imgexec_exec ( int argc, char **argv) {
  250. return imgsingle_exec ( argc, argv, &imgexec_desc );
  251. }
  252. /** "imgargs" command descriptor */
  253. static struct command_descriptor imgargs_cmd =
  254. COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
  255. 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
  256. /** "imgargs" family command descriptor */
  257. struct imgsingle_descriptor imgargs_desc = {
  258. .cmd = &imgargs_cmd,
  259. .acquire = imgacquire,
  260. .preaction = image_clear_cmdline,
  261. };
  262. /**
  263. * The "imgargs" command body
  264. *
  265. * @v argc Argument count
  266. * @v argv Argument list
  267. * @ret rc Return status code
  268. */
  269. static int imgargs_exec ( int argc, char **argv ) {
  270. return imgsingle_exec ( argc, argv, &imgargs_desc );
  271. }
  272. /** "img{multi}" options */
  273. struct imgmulti_options {};
  274. /** "img{multi}" option list */
  275. static struct option_descriptor imgmulti_opts[] = {};
  276. /** "img{multi}" command descriptor */
  277. static struct command_descriptor imgmulti_cmd =
  278. COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
  279. "[<image>...]" );
  280. /**
  281. * The "img{multi}" family of commands
  282. *
  283. * @v argc Argument count
  284. * @v argv Argument list
  285. * @v payload Function to execute on each image
  286. * @ret rc Return status code
  287. */
  288. static int imgmulti_exec ( int argc, char **argv,
  289. void ( * payload ) ( struct image *image ) ) {
  290. struct imgmulti_options opts;
  291. struct image *image;
  292. struct image *tmp;
  293. int i;
  294. int rc;
  295. /* Parse options */
  296. if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
  297. return rc;
  298. /* If no images are explicitly specified, process all images */
  299. if ( optind == argc ) {
  300. for_each_image_safe ( image, tmp )
  301. payload ( image );
  302. return 0;
  303. }
  304. /* Otherwise, process specified images */
  305. for ( i = optind ; i < argc ; i++ ) {
  306. image = find_image ( argv[i] );
  307. if ( ! image ) {
  308. printf ( "\"%s\": no such image\n", argv[i] );
  309. return -ENOENT;
  310. }
  311. payload ( image );
  312. }
  313. return 0;
  314. }
  315. /**
  316. * The "imgstat" command
  317. *
  318. * @v argc Argument count
  319. * @v argv Argument list
  320. * @ret rc Return status code
  321. */
  322. static int imgstat_exec ( int argc, char **argv ) {
  323. return imgmulti_exec ( argc, argv, imgstat );
  324. }
  325. /**
  326. * The "imgfree" command
  327. *
  328. * @v argc Argument count
  329. * @v argv Argument list
  330. * @ret rc Return status code
  331. */
  332. static int imgfree_exec ( int argc, char **argv ) {
  333. return imgmulti_exec ( argc, argv, unregister_image );
  334. }
  335. /** Image management commands */
  336. struct command image_commands[] __command = {
  337. {
  338. .name = "imgfetch",
  339. .exec = imgfetch_exec,
  340. },
  341. {
  342. .name = "module",
  343. .exec = imgfetch_exec, /* synonym for "imgfetch" */
  344. },
  345. {
  346. .name = "initrd",
  347. .exec = imgfetch_exec, /* synonym for "imgfetch" */
  348. },
  349. {
  350. .name = "kernel",
  351. .exec = imgselect_exec, /* synonym for "imgselect" */
  352. },
  353. {
  354. .name = "chain",
  355. .exec = imgexec_exec, /* synonym for "imgexec" */
  356. },
  357. {
  358. .name = "imgselect",
  359. .exec = imgselect_exec,
  360. },
  361. {
  362. .name = "imgload",
  363. .exec = imgselect_exec, /* synonym for "imgselect" */
  364. },
  365. {
  366. .name = "imgargs",
  367. .exec = imgargs_exec,
  368. },
  369. {
  370. .name = "imgexec",
  371. .exec = imgexec_exec,
  372. },
  373. {
  374. .name = "boot", /* synonym for "imgexec" */
  375. .exec = imgexec_exec,
  376. },
  377. {
  378. .name = "imgstat",
  379. .exec = imgstat_exec,
  380. },
  381. {
  382. .name = "imgfree",
  383. .exec = imgfree_exec,
  384. },
  385. };