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 
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 */
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 */
59  /* Other "img{single}" commands take only --name, --timeout,
60  * and --autofree
61  */
63 } opts = {
64  .imgexec = {
65  OPTION_DESC ( "name", 'n', required_argument,
67  OPTION_DESC ( "timeout", 't', required_argument,
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 */
78  /** Command descriptor */
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 {
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 )
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 */
189  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
190  1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
191 
192 /** "imgfetch" family command descriptor */
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 */
223  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
224  1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
225 
226 /** "imgselect" family command descriptor */
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 */
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 */
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 */
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 */
301  COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
302  1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
303 
304 /** "imgargs" family command descriptor */
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 */
324 
325 /** "img{multi}" option list */
326 static struct option_descriptor imgmulti_opts[] = {};
327 
328 /** "img{multi}" command descriptor */
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 ) {
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 };
static struct command_descriptor imgfetch_cmd
"imgfetch" command descriptor
Definition: image_cmd.c:188
struct imgsingle_descriptor imgargs_desc
"imgargs" family command descriptor
Definition: image_cmd.c:305
unsigned int flags
Flags.
Definition: image.h:36
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
int image_select(struct image *image)
Select image for execution.
Definition: image.c:429
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
Minimal command shell.
int optind
Current option index.
Definition: getopt.c:51
struct image * find_image(const char *name)
Find image by name.
Definition: image.c:270
Error codes.
A command-line command.
Definition: command.h:9
An "img{single}" family command descriptor.
Definition: image_cmd.c:77
int parse_timeout(char *text, unsigned long *value)
Parse timeout value (in ms)
Definition: parseopt.c:111
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct imgsingle_descriptor imgfetch_desc
"imgfetch" family command descriptor
Definition: image_cmd.c:193
int autofree
Free image after execution.
Definition: image_cmd.c:52
int parse_options(int argc, char **argv, struct command_descriptor *cmd, void *opts)
Parse command-line options.
Definition: parseopt.c:447
An executable image.
Definition: image.h:24
"img{multi}" options
Definition: image_cmd.c:323
A command descriptor.
Definition: parseopt.h:76
void shell_stop(int stop)
Set shell stop state.
Definition: exec.c:217
struct imgsingle_descriptor imgselect_desc
"imgselect" family command descriptor
Definition: image_cmd.c:227
static int imgselect_exec(int argc, char **argv)
The "imgselect" command.
Definition: image_cmd.c:241
#define IMAGE_AUTO_UNREGISTER
Image will be automatically unregistered after execution.
Definition: image.h:73
int image_exec(struct image *image)
Execute image.
Definition: image.c:291
struct command image_commands [] __command
Image management commands.
Definition: image_cmd.c:396
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct option_descriptor imgmulti_opts[]
"img{multi}" option list
Definition: image_cmd.c:326
static int imgmulti_exec(int argc, char **argv, void(*payload)(struct image *image))
The "img{multi}" family of commands.
Definition: image_cmd.c:341
Parse command-line options.
int parse_string(char *text, char **value)
Parse string value.
Definition: parseopt.c:70
Executable images.
struct option_descriptor imgsingle[3]
Definition: image_cmd.c:62
static int imgexec_exec(int argc, char **argv)
The "imgexec" command.
Definition: image_cmd.c:295
void imgstat(struct image *image)
Display status of an image.
Definition: imgmgmt.c:158
#define MAX_ARGUMENTS
No maximum number of arguments.
Definition: parseopt.h:96
struct option_descriptor imgexec[4]
Definition: image_cmd.c:58
char * concat_args(char **args)
Concatenate arguments.
Definition: exec.c:358
static int imgsingle_exec(int argc, char **argv, struct imgsingle_descriptor *desc)
The "img{single}" family of commands.
Definition: image_cmd.c:102
int parse_flag(char *text __unused, int *flag)
Parse flag.
Definition: parseopt.c:200
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static int imgargs_exec(int argc, char **argv)
The "imgargs" command body.
Definition: image_cmd.c:318
int image_replace(struct image *replacement)
Set replacement image.
Definition: image.c:393
#define for_each_image_safe(image, tmp)
Iterate over all registered images, safe against deletion.
Definition: image.h:153
int image_set_name(struct image *image, const char *name)
Set image name.
Definition: image.c:144
uint8_t * tmp
Definition: entropy.h:156
Command line option parsing.
static struct command_descriptor imgargs_cmd
"imgargs" command descriptor
Definition: image_cmd.c:300
struct command_descriptor * cmd
Command descriptor.
Definition: image_cmd.c:79
void(* preaction)(struct image *image)
Pre-action to take upon image, or NULL.
Definition: image_cmd.c:84
static struct command_descriptor imgexec_cmd
"imgexec" command descriptor
Definition: image_cmd.c:246
Option does not take an argument.
Definition: getopt.h:16
int(* action)(struct image *image, struct imgsingle_options *opts)
Action to take upon image, or NULL.
Definition: image_cmd.c:86
static int imgselect(struct image *image, struct imgsingle_options *opts __unused)
"imgselect" command action
Definition: image_cmd.c:216
const char * name
Name of the command.
Definition: command.h:11
static int imgstat_exec(int argc, char **argv)
The "imgstat" command.
Definition: image_cmd.c:380
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct image * image_find_selected(void)
Find selected image.
Definition: image.c:451
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:252
unsigned long timeout
Download timeout.
Definition: image_cmd.c:48
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Image management.
static struct command_descriptor imgmulti_cmd
"img{multi}" command descriptor
Definition: image_cmd.c:329
int imgdownload_string(const char *uri_string, unsigned long timeout, struct image **image)
Download a new image.
Definition: imgmgmt.c:119
#define OPTION_DESC(_longopt, _shortopt, _has_arg, _struct, _field, _parse)
Construct option descriptor.
Definition: parseopt.h:66
Option requires an argument.
Definition: getopt.h:18
Stop processing commands.
Definition: shell.h:29
A command-line option descriptor.
Definition: parseopt.h:22
static void image_clear_cmdline(struct image *image)
Clear image command line.
Definition: image.h:215
struct imgsingle_descriptor imgexec_desc
"imgexec" family command descriptor
Definition: image_cmd.c:281
#define COMMAND_DESC(_struct, _options, _min_args, _max_args, _usage)
Construct command descriptor.
Definition: parseopt.h:107
int image_set_cmdline(struct image *image, const char *cmdline)
Set image command line.
Definition: image.c:166
void timeout(int)
int replace
Replace image.
Definition: image_cmd.c:50
"img{single}" options
Definition: image_cmd.c:44
uint32_t cmdline
Definition: multiboot.h:16
static union @424 opts
"img{single}" option list
const char * verb
Verb to describe action.
Definition: image_cmd.c:89
int(* acquire)(const char *name, unsigned long timeout, struct image **image)
Function to use to acquire the image.
Definition: image_cmd.c:81
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static struct command_descriptor imgselect_cmd
"imgselect" command descriptor
Definition: image_cmd.c:222
static int imgfetch_exec(int argc, char **argv)
The "imgfetch" command.
Definition: image_cmd.c:205
char * name
Image name.
Definition: image_cmd.c:46
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition: imgmgmt.c:141
static int imgfree_exec(int argc, char **argv)
The "imgfree" command.
Definition: image_cmd.c:391