iPXE
image_cmd.c
Go to the documentation of this file.
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 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <getopt.h>
33 #include <ipxe/image.h>
34 #include <ipxe/command.h>
35 #include <ipxe/parseopt.h>
36 #include <ipxe/shell.h>
37 #include <usr/imgmgmt.h>
38 
39 /** @file
40  *
41  * Image management commands
42  *
43  */
44 
45 /** "img{single}" options */
47  /** Image name */
48  char *name;
49  /** Download timeout */
50  unsigned long timeout;
51  /** Replace image */
52  int replace;
53  /** Free image after execution */
54  int autofree;
55 };
56 
57 /** "img{single}" option list */
58 static union {
59  /* "imgexec" takes all three options */
61  /* Other "img{single}" commands take only --name, --timeout,
62  * and --autofree
63  */
65 } opts = {
66  .imgexec = {
67  OPTION_DESC ( "name", 'n', required_argument,
69  OPTION_DESC ( "timeout", 't', required_argument,
71  OPTION_DESC ( "autofree", 'a', no_argument,
72  struct imgsingle_options, autofree, parse_flag ),
73  OPTION_DESC ( "replace", 'r', no_argument,
74  struct imgsingle_options, replace, parse_flag ),
75  },
76 };
77 
78 /** An "img{single}" family command descriptor */
80  /** Command descriptor */
82  /** Function to use to acquire the image */
83  int ( * acquire ) ( const char *name, unsigned long timeout,
84  struct image **image );
85  /** Pre-action to take upon image, or NULL */
86  void ( * preaction ) ( struct image *image );
87  /** Action to take upon image, or NULL */
88  int ( * action ) ( struct image *image,
89  struct imgsingle_options *opts );
90  /** Verb to describe action */
91  const char *verb;
92 };
93 
94 /**
95  * The "img{single}" family of commands
96  *
97  * @v argc Argument count
98  * @v argv Argument list
99  * @v desc "img{single}" command descriptor
100  * @v action_name Action name (for error messages)
101  * @v action Action to take upon image
102  * @ret rc Return status code
103  */
104 static int imgsingle_exec ( int argc, char **argv,
105  struct imgsingle_descriptor *desc ) {
106  struct imgsingle_options opts;
107  char *name_uri = NULL;
108  char *cmdline = NULL;
109  struct image *image;
110  int rc;
111 
112  /* Parse options */
113  if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
114  goto err_parse_options;
115 
116  /* Parse name/URI string and command line, if present */
117  if ( optind < argc ) {
118  name_uri = argv[optind];
119  if ( argv[ optind + 1 ] != NULL ) {
120  cmdline = concat_args ( &argv[ optind + 1 ] );
121  if ( ! cmdline ) {
122  rc = -ENOMEM;
123  goto err_parse_cmdline;
124  }
125  }
126  }
127 
128  /* Acquire the image */
129  if ( name_uri ) {
130  if ( ( rc = desc->acquire ( name_uri, opts.timeout,
131  &image ) ) != 0 )
132  goto err_acquire;
133  } else {
135  if ( ! image ) {
136  printf ( "No image selected\n" );
137  goto err_acquire;
138  }
139  }
140 
141  /* Carry out command pre-action, if applicable */
142  if ( desc->preaction )
143  desc->preaction ( image );
144 
145  /* Set the image name, if applicable */
146  if ( opts.name ) {
147  if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
148  printf ( "Could not name image: %s\n",
149  strerror ( rc ) );
150  goto err_set_name;
151  }
152  }
153 
154  /* Set the command-line arguments, if applicable */
155  if ( cmdline ) {
156  if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
157  printf ( "Could not set arguments: %s\n",
158  strerror ( rc ) );
159  goto err_set_cmdline;
160  }
161  }
162 
163  /* Set the auto-unregister flag, if applicable */
164  if ( opts.autofree )
166 
167  /* Carry out command action, if applicable */
168  if ( desc->action ) {
169  if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
170  printf ( "Could not %s: %s\n",
171  desc->verb, strerror ( rc ) );
172  goto err_action;
173  }
174  }
175 
176  /* Success */
177  rc = 0;
178 
179  err_action:
180  err_set_cmdline:
181  err_set_name:
182  err_acquire:
183  free ( cmdline );
184  err_parse_cmdline:
185  err_parse_options:
186  return rc;
187 }
188 
189 /** "imgfetch" command descriptor */
191  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
192  1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
193 
194 /** "imgfetch" family command descriptor */
196  .cmd = &imgfetch_cmd,
197  .acquire = imgdownload_string,
198 };
199 
200 /**
201  * The "imgfetch" command
202  *
203  * @v argc Argument count
204  * @v argv Argument list
205  * @ret rc Return status code
206  */
207 static int imgfetch_exec ( int argc, char **argv ) {
208  return imgsingle_exec ( argc, argv, &imgfetch_desc );
209 }
210 
211 /**
212  * "imgselect" command action
213  *
214  * @v image Image
215  * @v opts Options
216  * @ret rc Return status code
217  */
218 static int imgselect ( struct image *image,
219  struct imgsingle_options *opts __unused ) {
220  return image_select ( image );
221 }
222 
223 /** "imgselect" command descriptor */
225  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
226  1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
227 
228 /** "imgselect" family command descriptor */
230  .cmd = &imgselect_cmd,
231  .acquire = imgacquire,
232  .action = imgselect,
233  .verb = "select",
234 };
235 
236 /**
237  * The "imgselect" command
238  *
239  * @v argc Argument count
240  * @v argv Argument list
241  * @ret rc Return status code
242  */
243 static int imgselect_exec ( int argc, char **argv ) {
244  return imgsingle_exec ( argc, argv, &imgselect_desc );
245 }
246 
247 /** "imgexec" command descriptor */
249  COMMAND_DESC ( struct imgsingle_options, opts.imgexec,
250  0, MAX_ARGUMENTS, "[<uri|image> [<arguments>...]]" );
251 
252 /**
253  * "imgexec" command action
254  *
255  * @v image Image
256  * @v opts Options
257  * @ret rc Return status code
258  */
259 static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
260  int rc;
261 
262  /* Perform replacement or execution as applicable */
263  if ( opts->replace ) {
264 
265  /* Try to replace image */
266  if ( ( rc = image_replace ( image ) ) != 0 )
267  return rc;
268 
269  /* Stop script and tail-recurse into replacement image */
271 
272  } else {
273 
274  /* Try to execute image */
275  if ( ( rc = image_exec ( image ) ) != 0 )
276  return rc;
277  }
278 
279  return 0;
280 }
281 
282 /** "imgexec" family command descriptor */
284  .cmd = &imgexec_cmd,
285  .acquire = imgacquire,
286  .action = imgexec,
287  .verb = "boot",
288 };
289 
290 /**
291  * The "imgexec" command
292  *
293  * @v argc Argument count
294  * @v argv Argument list
295  * @ret rc Return status code
296  */
297 static int imgexec_exec ( int argc, char **argv) {
298  return imgsingle_exec ( argc, argv, &imgexec_desc );
299 }
300 
301 /** "imgargs" command descriptor */
303  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
304  1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
305 
306 /** "imgargs" family command descriptor */
308  .cmd = &imgargs_cmd,
309  .acquire = imgacquire,
310  .preaction = image_clear_cmdline,
311 };
312 
313 /**
314  * The "imgargs" command body
315  *
316  * @v argc Argument count
317  * @v argv Argument list
318  * @ret rc Return status code
319  */
320 static int imgargs_exec ( int argc, char **argv ) {
321  return imgsingle_exec ( argc, argv, &imgargs_desc );
322 }
323 
324 /** "img{multi}" options */
326 
327 /** "img{multi}" option list */
328 static struct option_descriptor imgmulti_opts[] = {};
329 
330 /** "img{multi}" command descriptor */
333  "[<image>...]" );
334 
335 /**
336  * The "img{multi}" family of commands
337  *
338  * @v argc Argument count
339  * @v argv Argument list
340  * @v payload Function to execute on each image
341  * @ret rc Return status code
342  */
343 static int imgmulti_exec ( int argc, char **argv,
344  void ( * payload ) ( struct image *image ) ) {
345  struct imgmulti_options opts;
346  struct image *image;
347  struct image *tmp;
348  int i;
349  int rc;
350 
351  /* Parse options */
352  if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
353  return rc;
354 
355  /* If no images are explicitly specified, process all images */
356  if ( optind == argc ) {
358  payload ( image );
359  return 0;
360  }
361 
362  /* Otherwise, process specified images */
363  for ( i = optind ; i < argc ; i++ ) {
364  image = find_image ( argv[i] );
365  if ( ! image ) {
366  printf ( "\"%s\": no such image\n", argv[i] );
367  return -ENOENT;
368  }
369  payload ( image );
370  }
371 
372  return 0;
373 }
374 
375 /**
376  * The "imgstat" command
377  *
378  * @v argc Argument count
379  * @v argv Argument list
380  * @ret rc Return status code
381  */
382 static int imgstat_exec ( int argc, char **argv ) {
383  return imgmulti_exec ( argc, argv, imgstat );
384 }
385 
386 /**
387  * The "imgfree" command
388  *
389  * @v argc Argument count
390  * @v argv Argument list
391  * @ret rc Return status code
392  */
393 static int imgfree_exec ( int argc, char **argv ) {
394  return imgmulti_exec ( argc, argv, unregister_image );
395 }
396 
397 /* "imgfetch" and synonyms */
398 COMMAND ( imgfetch, imgfetch_exec );
399 COMMAND ( module, imgfetch_exec );
400 COMMAND ( initrd, imgfetch_exec );
401 
402 /* "imgselect" and synonyms */
404 COMMAND ( imgload, imgselect_exec );
406 
407 /* "imgexec" and synonyms */
409 COMMAND ( chain, imgexec_exec );
410 COMMAND ( boot, imgexec_exec );
411 
412 /* Other image management commands */
413 COMMAND ( imgargs, imgargs_exec );
415 COMMAND ( imgfree, imgfree_exec );
static struct command_descriptor imgfetch_cmd
"imgfetch" command descriptor
Definition: image_cmd.c:190
struct imgsingle_descriptor imgargs_desc
"imgargs" family command descriptor
Definition: image_cmd.c:307
unsigned int flags
Flags.
Definition: image.h:40
struct image_tag selected_image
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
int image_select(struct image *image)
Select image for execution.
Definition: image.c:565
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:465
Minimal command shell.
int optind
Current option index.
Definition: getopt.c:52
struct image * find_image(const char *name)
Find image by name.
Definition: image.c:376
Error codes.
An "img{single}" family command descriptor.
Definition: image_cmd.c:79
int parse_timeout(char *text, unsigned long *value)
Parse timeout value (in ms)
Definition: parseopt.c:115
#define ENOENT
No such file or directory.
Definition: errno.h:515
struct imgsingle_descriptor imgfetch_desc
"imgfetch" family command descriptor
Definition: image_cmd.c:195
int autofree
Free image after execution.
Definition: image_cmd.c:54
int parse_options(int argc, char **argv, struct command_descriptor *cmd, void *opts)
Parse command-line options.
Definition: parseopt.c:485
COMMAND(imgfetch, imgfetch_exec)
An executable image.
Definition: image.h:24
FILE_SECBOOT(PERMITTED)
"img{multi}" options
Definition: image_cmd.c:325
A command descriptor.
Definition: parseopt.h:78
void shell_stop(int stop)
Set shell stop state.
Definition: exec.c:218
struct imgsingle_descriptor imgselect_desc
"imgselect" family command descriptor
Definition: image_cmd.c:229
static int imgselect_exec(int argc, char **argv)
The "imgselect" command.
Definition: image_cmd.c:243
#define IMAGE_AUTO_UNREGISTER
Image will be automatically unregistered after execution.
Definition: image.h:83
int image_exec(struct image *image)
Execute image.
Definition: image.c:414
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition: image.c:393
unsigned long tmp
Definition: linux_pci.h:65
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
#define ENOMEM
Not enough space.
Definition: errno.h:535
static struct option_descriptor imgmulti_opts[]
"img{multi}" option list
Definition: image_cmd.c:328
static int imgmulti_exec(int argc, char **argv, void(*payload)(struct image *image))
The "img{multi}" family of commands.
Definition: image_cmd.c:343
Parse command-line options.
int parse_string(char *text, char **value)
Parse string value.
Definition: parseopt.c:74
Executable images.
struct option_descriptor imgsingle[3]
Definition: image_cmd.c:64
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static int imgexec_exec(int argc, char **argv)
The "imgexec" command.
Definition: image_cmd.c:297
void imgstat(struct image *image)
Display status of an image.
Definition: imgmgmt.c:160
#define MAX_ARGUMENTS
No maximum number of arguments.
Definition: parseopt.h:98
struct option_descriptor imgexec[4]
Definition: image_cmd.c:60
char * concat_args(char **args)
Concatenate arguments.
Definition: exec.c:359
uint32_t kernel
Kernel version (numeric)
Definition: ena.h:20
static int imgsingle_exec(int argc, char **argv, struct imgsingle_descriptor *desc)
The "img{single}" family of commands.
Definition: image_cmd.c:104
int parse_flag(char *text __unused, int *flag)
Parse flag.
Definition: parseopt.c:227
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
static int imgargs_exec(int argc, char **argv)
The "imgargs" command body.
Definition: image_cmd.c:320
int image_replace(struct image *replacement)
Set replacement image.
Definition: image.c:529
#define for_each_image_safe(image, tmp)
Iterate over all registered images, safe against deletion.
Definition: image.h:195
int image_set_name(struct image *image, const char *name)
Set image name.
Definition: image.c:181
Command line option parsing.
static struct command_descriptor imgargs_cmd
"imgargs" command descriptor
Definition: image_cmd.c:302
struct command_descriptor * cmd
Command descriptor.
Definition: image_cmd.c:81
void(* preaction)(struct image *image)
Pre-action to take upon image, or NULL.
Definition: image_cmd.c:86
static struct command_descriptor imgexec_cmd
"imgexec" command descriptor
Definition: image_cmd.c:248
Option does not take an argument.
Definition: getopt.h:17
int(* action)(struct image *image, struct imgsingle_options *opts)
Action to take upon image, or NULL.
Definition: image_cmd.c:88
static int imgselect(struct image *image, struct imgsingle_options *opts __unused)
"imgselect" command action
Definition: image_cmd.c:218
static int imgstat_exec(int argc, char **argv)
The "imgstat" command.
Definition: image_cmd.c:382
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:358
unsigned long timeout
Download timeout.
Definition: image_cmd.c:50
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Image management.
static struct command_descriptor imgmulti_cmd
"img{multi}" command descriptor
Definition: image_cmd.c:331
int imgdownload_string(const char *uri_string, unsigned long timeout, struct image **image)
Download a new image.
Definition: imgmgmt.c:121
#define OPTION_DESC(_longopt, _shortopt, _has_arg, _struct, _field, _parse)
Construct option descriptor.
Definition: parseopt.h:68
Option requires an argument.
Definition: getopt.h:19
Stop processing commands.
Definition: shell.h:30
A command-line option descriptor.
Definition: parseopt.h:24
static void image_clear_cmdline(struct image *image)
Clear image command line.
Definition: image.h:259
struct imgsingle_descriptor imgexec_desc
"imgexec" family command descriptor
Definition: image_cmd.c:283
#define COMMAND_DESC(_struct, _options, _min_args, _max_args, _usage)
Construct command descriptor.
Definition: parseopt.h:109
int image_set_cmdline(struct image *image, const char *cmdline)
Set image command line.
Definition: image.c:226
void timeout(int)
int replace
Replace image.
Definition: image_cmd.c:52
"img{single}" options
Definition: image_cmd.c:46
uint32_t cmdline
Definition: multiboot.h:16
const char * verb
Verb to describe action.
Definition: image_cmd.c:91
int(* acquire)(const char *name, unsigned long timeout, struct image **image)
Function to use to acquire the image.
Definition: image_cmd.c:83
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static struct command_descriptor imgselect_cmd
"imgselect" command descriptor
Definition: image_cmd.c:224
String functions.
static int imgfetch_exec(int argc, char **argv)
The "imgfetch" command.
Definition: image_cmd.c:207
char * name
Image name.
Definition: image_cmd.c:48
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition: imgmgmt.c:143
static union @448 opts
"img{single}" option list
static int imgfree_exec(int argc, char **argv)
The "imgfree" command.
Definition: image_cmd.c:393