Browse Source

[image] Add "--replace" option

Expose image tail-recursion to iPXE scripts via the "--replace"
option.  This functions similarly to exec() under Unix: the
currently-executing script is replaced with the new image (as opposed
to running the new image as a subroutine).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
5d3c368efb
2 changed files with 64 additions and 11 deletions
  1. 10
    6
      src/core/image.c
  2. 54
    5
      src/hci/commands/image_cmd.c

+ 10
- 6
src/core/image.c View File

327
 	if ( image->flags & IMAGE_AUTO_UNREGISTER )
327
 	if ( image->flags & IMAGE_AUTO_UNREGISTER )
328
 		unregister_image ( image );
328
 		unregister_image ( image );
329
 
329
 
330
+	/* Debug message for tail-recursion.  Placed here because the
331
+	 * image_put() may end up freeing the image.
332
+	 */
333
+	if ( replacement ) {
334
+		DBGC ( image, "IMAGE %s replacing self with IMAGE %s\n",
335
+		       image->name, replacement->name );
336
+	}
337
+
330
 	/* Drop temporary reference to the original image */
338
 	/* Drop temporary reference to the original image */
331
 	image_put ( image );
339
 	image_put ( image );
332
 
340
 
338
 	uri_put ( old_cwuri );
346
 	uri_put ( old_cwuri );
339
 
347
 
340
 	/* Tail-recurse into replacement image, if one exists */
348
 	/* Tail-recurse into replacement image, if one exists */
341
-	if ( replacement ) {
342
-		DBGC ( image, "IMAGE <freed> replacing self with IMAGE %s\n",
343
-		       replacement->name );
344
-		if ( ( rc = image_exec ( replacement ) ) != 0 )
345
-			return rc;
346
-	}
349
+	if ( replacement )
350
+		return image_exec ( replacement );
347
 
351
 
348
 	return rc;
352
 	return rc;
349
 }
353
 }

+ 54
- 5
src/hci/commands/image_cmd.c View File

26
 #include <ipxe/image.h>
26
 #include <ipxe/image.h>
27
 #include <ipxe/command.h>
27
 #include <ipxe/command.h>
28
 #include <ipxe/parseopt.h>
28
 #include <ipxe/parseopt.h>
29
+#include <ipxe/shell.h>
29
 #include <usr/imgmgmt.h>
30
 #include <usr/imgmgmt.h>
30
 
31
 
31
 /** @file
32
 /** @file
38
 struct imgsingle_options {
39
 struct imgsingle_options {
39
 	/** Image name */
40
 	/** Image name */
40
 	const char *name;
41
 	const char *name;
42
+	/** Replace image */
43
+	int replace;
41
 	/** Free image after execution */
44
 	/** Free image after execution */
42
 	int autofree;
45
 	int autofree;
43
 };
46
 };
46
 static struct option_descriptor imgsingle_opts[] = {
49
 static struct option_descriptor imgsingle_opts[] = {
47
 	OPTION_DESC ( "name", 'n', required_argument,
50
 	OPTION_DESC ( "name", 'n', required_argument,
48
 		      struct imgsingle_options, name, parse_string ),
51
 		      struct imgsingle_options, name, parse_string ),
52
+	OPTION_DESC ( "replace", 'r', no_argument,
53
+		      struct imgsingle_options, replace, parse_flag ),
49
 	OPTION_DESC ( "autofree", 'a', no_argument,
54
 	OPTION_DESC ( "autofree", 'a', no_argument,
50
 		      struct imgsingle_options, autofree, parse_flag ),
55
 		      struct imgsingle_options, autofree, parse_flag ),
51
 };
56
 };
66
 	/** Pre-action to take upon image, or NULL */
71
 	/** Pre-action to take upon image, or NULL */
67
 	void ( * preaction ) ( struct image *image );
72
 	void ( * preaction ) ( struct image *image );
68
 	/** Action to take upon image, or NULL */
73
 	/** Action to take upon image, or NULL */
69
-	int ( * action ) ( struct image *image );
74
+	int ( * action ) ( struct image *image,
75
+			   struct imgsingle_options *opts );
70
 	/** Verb to describe action */
76
 	/** Verb to describe action */
71
 	const char *verb;
77
 	const char *verb;
72
 };
78
 };
145
 
151
 
146
 	/* Carry out command action, if applicable */
152
 	/* Carry out command action, if applicable */
147
 	if ( desc->action ) {
153
 	if ( desc->action ) {
148
-		if ( ( rc = desc->action ( image ) ) != 0 ) {
154
+		if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
149
 			printf ( "Could not %s: %s\n",
155
 			printf ( "Could not %s: %s\n",
150
 				 desc->verb, strerror ( rc ) );
156
 				 desc->verb, strerror ( rc ) );
151
 			goto err_action;
157
 			goto err_action;
188
 	return imgsingle_exec ( argc, argv, &imgfetch_desc );
194
 	return imgsingle_exec ( argc, argv, &imgfetch_desc );
189
 }
195
 }
190
 
196
 
197
+/**
198
+ * "imgselect" command action
199
+ *
200
+ * @v image		Image
201
+ * @v opts		Options
202
+ * @ret rc		Return status code
203
+ */
204
+static int imgselect ( struct image *image,
205
+		       struct imgsingle_options *opts __unused ) {
206
+	return image_select ( image );
207
+}
208
+
191
 /** "imgselect" family command descriptor */
209
 /** "imgselect" family command descriptor */
192
 struct imgsingle_descriptor imgselect_desc = {
210
 struct imgsingle_descriptor imgselect_desc = {
193
 	.cmd = &imgsingle_cmd,
211
 	.cmd = &imgsingle_cmd,
194
 	.acquire = imgacquire,
212
 	.acquire = imgacquire,
195
-	.action = image_select,
213
+	.action = imgselect,
196
 	.verb = "select",
214
 	.verb = "select",
197
 };
215
 };
198
 
216
 
211
 static struct command_descriptor imgexec_cmd =
229
 static struct command_descriptor imgexec_cmd =
212
 	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
230
 	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
213
 		       0, MAX_ARGUMENTS,
231
 		       0, MAX_ARGUMENTS,
214
-		       "[--autofree] [<uri|image> [<arguments>...]]" );
232
+		       "[--autofree] [--replace] "
233
+		       "[<uri|image> [<arguments>...]]" );
234
+
235
+/**
236
+ * "imgexec" command action
237
+ *
238
+ * @v image		Image
239
+ * @v opts		Options
240
+ * @ret rc		Return status code
241
+ */
242
+static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
243
+	int rc;
244
+
245
+	/* Perform replacement or execution as applicable */
246
+	if ( opts->replace ) {
247
+
248
+		/* Try to replace image */
249
+		if ( ( rc = image_replace ( image ) ) != 0 )
250
+			return rc;
251
+
252
+		/* Stop script and tail-recurse into replacement image */
253
+		shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
254
+
255
+	} else {
256
+
257
+		/* Try to execute image */
258
+		if ( ( rc = image_exec ( image ) ) != 0 )
259
+			return rc;
260
+	}
261
+
262
+	return 0;
263
+}
215
 
264
 
216
 /** "imgexec" family command descriptor */
265
 /** "imgexec" family command descriptor */
217
 struct imgsingle_descriptor imgexec_desc = {
266
 struct imgsingle_descriptor imgexec_desc = {
218
 	.cmd = &imgexec_cmd,
267
 	.cmd = &imgexec_cmd,
219
 	.acquire = imgacquire,
268
 	.acquire = imgacquire,
220
-	.action = image_exec,
269
+	.action = imgexec,
221
 	.verb = "boot",
270
 	.verb = "boot",
222
 };
271
 };
223
 
272
 

Loading…
Cancel
Save