Browse Source

[image] Simplify use of imgdownload()

Allow imgdownload() to be called without first having to allocate (and
so keep track of) an image.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
9fa4ac2e9a

+ 3
- 4
src/arch/i386/image/com32.c View File

132
 		break;
132
 		break;
133
 
133
 
134
 	case COMBOOT_EXIT_RUN_KERNEL:
134
 	case COMBOOT_EXIT_RUN_KERNEL:
135
-		DBGC ( image, "COM32 %p: exited to run kernel %p\n",
136
-		       image, comboot_replacement_image );
137
-		image->replacement = comboot_replacement_image;
138
-		comboot_replacement_image = NULL;
135
+		assert ( image->replacement );
136
+		DBGC ( image, "COM32 %p: exited to run kernel %s\n",
137
+		       image, image->replacement->name );
139
 		break;
138
 		break;
140
 
139
 
141
 	case COMBOOT_EXIT_COMMAND:
140
 	case COMBOOT_EXIT_COMMAND:

+ 3
- 4
src/arch/i386/image/comboot.c View File

188
 		break;
188
 		break;
189
 
189
 
190
 	case COMBOOT_EXIT_RUN_KERNEL:
190
 	case COMBOOT_EXIT_RUN_KERNEL:
191
-		DBGC ( image, "COMBOOT %p: exited to run kernel %p\n",
192
-		       image, comboot_replacement_image );
193
-		image->replacement = comboot_replacement_image;
194
-		comboot_replacement_image = NULL;
191
+		assert ( image->replacement );
192
+		DBGC ( image, "COMBOOT %p: exited to run kernel %s\n",
193
+		       image, image->replacement->name );
195
 		break;
194
 		break;
196
 
195
 
197
 	case COMBOOT_EXIT_COMMAND:
196
 	case COMBOOT_EXIT_COMMAND:

+ 0
- 3
src/arch/i386/include/comboot.h View File

161
 /* setjmp/longjmp context buffer used to return after loading an image */
161
 /* setjmp/longjmp context buffer used to return after loading an image */
162
 extern rmjmp_buf comboot_return;
162
 extern rmjmp_buf comboot_return;
163
 
163
 
164
-/* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */
165
-extern struct image *comboot_replacement_image;
166
-
167
 extern void *com32_external_esp;
164
 extern void *com32_external_esp;
168
 
165
 
169
 #define COMBOOT_EXIT 1
166
 #define COMBOOT_EXIT 1

+ 8
- 41
src/arch/i386/interface/syslinux/comboot_call.c View File

81
 /* setjmp/longjmp context buffer used to return after loading an image */
81
 /* setjmp/longjmp context buffer used to return after loading an image */
82
 rmjmp_buf comboot_return;
82
 rmjmp_buf comboot_return;
83
 
83
 
84
-/* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */
85
-struct image *comboot_replacement_image;
86
-
87
 /* Mode flags set by INT 22h AX=0017h */
84
 /* Mode flags set by INT 22h AX=0017h */
88
 static uint16_t comboot_graphics_mode = 0;
85
 static uint16_t comboot_graphics_mode = 0;
89
 
86
 
169
  * Fetch kernel and optional initrd
166
  * Fetch kernel and optional initrd
170
  */
167
  */
171
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
168
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
172
-	struct image *kernel = NULL;
173
-	struct image *initrd = NULL;
174
 	char *initrd_file;
169
 	char *initrd_file;
175
 	int rc;
170
 	int rc;
176
 
171
 
188
 
183
 
189
 		DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file );
184
 		DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file );
190
 
185
 
191
-		/* Allocate and fetch initrd */
192
-		initrd = alloc_image();
193
-		if ( ! initrd ) {
194
-			DBG ( "COMBOOT: could not allocate initrd\n" );
195
-			rc = -ENOMEM;
196
-			goto out;
197
-		}
198
-		if ( ( rc = imgfetch ( initrd, initrd_file,
199
-				       register_image ) ) != 0 ) {
186
+		/* Fetch initrd */
187
+		if ( ( rc = imgdownload_string ( initrd_file, NULL, NULL,
188
+						 register_and_put_image ))!=0){
200
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
189
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
201
 			      strerror ( rc ) );
190
 			      strerror ( rc ) );
202
-			goto out;
191
+			return rc;
203
 		}
192
 		}
204
 
193
 
205
 		/* Restore space after initrd name, if applicable */
194
 		/* Restore space after initrd name, if applicable */
210
 	DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
199
 	DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
211
 
200
 
212
 	/* Allocate and fetch kernel */
201
 	/* Allocate and fetch kernel */
213
-	kernel = alloc_image();
214
-	if ( ! kernel ) {
215
-		DBG ( "COMBOOT: could not allocate kernel\n" );
216
-		rc = -ENOMEM;
217
-		goto out;
218
-	}
219
-	if ( ( rc = imgfetch ( kernel, kernel_file,
220
-			       register_and_select_image ) ) != 0 ) {
202
+	if ( ( rc = imgdownload_string ( kernel_file, NULL, cmdline,
203
+					 register_and_replace_image ) ) != 0 ) {
221
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
204
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
222
 		      strerror ( rc ) );
205
 		      strerror ( rc ) );
223
-		goto out;
224
-	}
225
-	if ( ( rc = image_set_cmdline ( kernel, cmdline ) ) != 0 ) {
226
-		DBG ( "COMBOOT: could not set kernel command line: %s\n",
227
-		      strerror ( rc ) );
228
-		goto out;
206
+		return rc;
229
 	}
207
 	}
230
 
208
 
231
-	/* Store kernel as replacement image */
232
-	assert ( comboot_replacement_image == NULL );
233
-	comboot_replacement_image = image_get ( kernel );
234
-
235
- out:
236
-	/* Drop image references unconditionally; either we want to
237
-	 * discard them, or they have been registered and we should
238
-	 * drop out local reference.
239
-	 */
240
-	image_put ( kernel );
241
-	image_put ( initrd );
242
-	return rc;
209
+	return 0;
243
 }
210
 }
244
 
211
 
245
 
212
 

+ 50
- 1
src/core/image.c View File

130
 
130
 
131
 	/* Add to image list */
131
 	/* Add to image list */
132
 	image_get ( image );
132
 	image_get ( image );
133
+	image->flags |= IMAGE_REGISTERED;
133
 	list_add_tail ( &image->list, &images );
134
 	list_add_tail ( &image->list, &images );
134
 	DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n",
135
 	DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n",
135
 	       image->name, user_to_phys ( image->data, 0 ),
136
 	       image->name, user_to_phys ( image->data, 0 ),
144
  * @v image		Executable image
145
  * @v image		Executable image
145
  */
146
  */
146
 void unregister_image ( struct image *image ) {
147
 void unregister_image ( struct image *image ) {
148
+
147
 	DBGC ( image, "IMAGE %s unregistered\n", image->name );
149
 	DBGC ( image, "IMAGE %s unregistered\n", image->name );
148
 	list_del ( &image->list );
150
 	list_del ( &image->list );
151
+	image->flags &= ~IMAGE_REGISTERED;
149
 	image_put ( image );
152
 	image_put ( image );
150
 }
153
 }
151
 
154
 
201
  *
204
  *
202
  * @v image		Executable image
205
  * @v image		Executable image
203
  * @ret rc		Return status code
206
  * @ret rc		Return status code
207
+ *
208
+ * The image must already be registered.  Note that executing an image
209
+ * may cause it to unregister itself.  The caller must therefore
210
+ * assume that the image pointer becomes invalid.
204
  */
211
  */
205
 int image_exec ( struct image *image ) {
212
 int image_exec ( struct image *image ) {
206
 	struct image *saved_current_image;
213
 	struct image *saved_current_image;
208
 	struct uri *old_cwuri;
215
 	struct uri *old_cwuri;
209
 	int rc;
216
 	int rc;
210
 
217
 
218
+	/* Sanity check */
219
+	assert ( image->flags & IMAGE_REGISTERED );
220
+
211
 	/* Check that this image can be executed */
221
 	/* Check that this image can be executed */
212
 	if ( ( rc = image_probe ( image ) ) != 0 )
222
 	if ( ( rc = image_probe ( image ) ) != 0 )
213
 		return rc;
223
 		return rc;
233
 	}
243
 	}
234
 
244
 
235
 	/* Pick up replacement image before we drop the original
245
 	/* Pick up replacement image before we drop the original
236
-	 * image's temporary reference.
246
+	 * image's temporary reference.  The replacement image must
247
+	 * already be registered, so we don't need to hold a temporary
248
+	 * reference (which would complicate the tail-recursion).
237
 	 */
249
 	 */
238
 	replacement = image->replacement;
250
 	replacement = image->replacement;
251
+	if ( replacement )
252
+		assert ( replacement->flags & IMAGE_REGISTERED );
239
 
253
 
240
 	/* Drop temporary reference to the original image */
254
 	/* Drop temporary reference to the original image */
241
 	image_put ( image );
255
 	image_put ( image );
258
 	return rc;
272
 	return rc;
259
 }
273
 }
260
 
274
 
275
+/**
276
+ * Set replacement image
277
+ *
278
+ * @v replacement	Replacement image
279
+ * @ret rc		Return status code
280
+ *
281
+ * The replacement image must already be registered, and must remain
282
+ * registered until the currently-executing image returns.
283
+ */
284
+int image_replace ( struct image *replacement ) {
285
+	struct image *image = current_image;
286
+	int rc;
287
+
288
+	/* Sanity check */
289
+	assert ( replacement->flags & IMAGE_REGISTERED );
290
+
291
+	/* Fail unless there is a currently-executing image */
292
+	if ( ! image ) {
293
+		rc = -ENOTTY;
294
+		DBGC ( replacement, "IMAGE %s cannot replace non-existent "
295
+		       "image: %s\n", replacement->name, strerror ( rc ) );
296
+		return rc;
297
+	}
298
+
299
+	/* Clear any existing replacement */
300
+	image_put ( image->replacement );
301
+
302
+	/* Set replacement */
303
+	image->replacement = image_get ( replacement );
304
+	DBGC ( image, "IMAGE %s will replace self with IMAGE %s\n",
305
+	       image->name, replacement->name );
306
+
307
+	return 0;
308
+}
309
+
261
 /**
310
 /**
262
  * Select image for execution
311
  * Select image for execution
263
  *
312
  *

+ 55
- 56
src/hci/commands/image_cmd.c View File

35
  *
35
  *
36
  */
36
  */
37
 
37
 
38
-/**
39
- * Fill in image command line
40
- *
41
- * @v image		Image
42
- * @v args		Argument list
43
- * @ret rc		Return status code
44
- */
45
-static int imgfill_cmdline ( struct image *image, char **args ) {
46
-	char *cmdline = NULL;
47
-	int rc;
48
-
49
-	/* Construct command line (if arguments are present) */
50
-	if ( *args ) {
51
-		cmdline = concat_args ( args );
52
-		if ( ! cmdline )
53
-			return -ENOMEM;
54
-	}
55
-
56
-	/* Apply command line */
57
-	rc = image_set_cmdline ( image, cmdline );
58
-	free ( cmdline );
59
-	return rc;
60
-}
61
-
62
 /** "imgfetch" options */
38
 /** "imgfetch" options */
63
 struct imgfetch_options {
39
 struct imgfetch_options {
64
 	/** Image name */
40
 	/** Image name */
82
  * @v argc		Argument count
58
  * @v argc		Argument count
83
  * @v argv		Argument list
59
  * @v argv		Argument list
84
  * @v cmd		Command descriptor
60
  * @v cmd		Command descriptor
61
+ * @v action_name	Action name (for error messages)
85
  * @v action		Action to take upon a successful download
62
  * @v action		Action to take upon a successful download
86
  * @ret rc		Return status code
63
  * @ret rc		Return status code
87
  */
64
  */
88
 static int imgfetch_core_exec ( int argc, char **argv,
65
 static int imgfetch_core_exec ( int argc, char **argv,
89
-				struct command_descriptor *cmd,
66
+				const char *action_name,
90
 				int ( * action ) ( struct image *image ) ) {
67
 				int ( * action ) ( struct image *image ) ) {
91
 	struct imgfetch_options opts;
68
 	struct imgfetch_options opts;
92
-	struct image *image;
93
 	char *uri_string;
69
 	char *uri_string;
70
+	char *cmdline = NULL;
94
 	int rc;
71
 	int rc;
95
 
72
 
96
 	/* Parse options */
73
 	/* Parse options */
97
-	if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
98
-		return rc;
74
+	if ( ( rc = parse_options ( argc, argv, &imgfetch_cmd, &opts ) ) != 0 )
75
+		goto err_parse_options;
99
 
76
 
100
 	/* Parse URI string */
77
 	/* Parse URI string */
101
 	uri_string = argv[optind];
78
 	uri_string = argv[optind];
102
 	if ( ! opts.name )
79
 	if ( ! opts.name )
103
 		opts.name = basename ( uri_string );
80
 		opts.name = basename ( uri_string );
104
 
81
 
105
-	/* Allocate image */
106
-	image = alloc_image();
107
-	if ( ! image ) {
108
-		printf ( "%s\n", strerror ( -ENOMEM ) );
109
-		return -ENOMEM;
82
+	/* Parse command line */
83
+	if ( argv[ optind + 1 ] != NULL ) {
84
+		cmdline = concat_args ( &argv[ optind + 1 ] );
85
+		if ( ! cmdline ) {
86
+			rc = -ENOMEM;
87
+			goto err_cmdline;
88
+		}
110
 	}
89
 	}
111
 
90
 
112
-	/* Fill in image name */
113
-	if ( ( rc = image_set_name ( image, opts.name ) ) != 0 )
114
-		return rc;
115
-
116
-	/* Fill in command line */
117
-	if ( ( rc = imgfill_cmdline ( image, &argv[ optind + 1 ] ) ) != 0 )
118
-		return rc;
119
-
120
 	/* Fetch the image */
91
 	/* Fetch the image */
121
-	if ( ( rc = imgfetch ( image, uri_string, action ) ) != 0 ) {
122
-		printf ( "Could not fetch %s: %s\n",
123
-			 uri_string, strerror ( rc ) );
124
-		image_put ( image );
125
-		return rc;
92
+	if ( ( rc = imgdownload_string ( uri_string, opts.name, cmdline,
93
+					 action ) ) != 0 ) {
94
+		printf ( "Could not %s %s: %s\n",
95
+			 action_name, uri_string, strerror ( rc ) );
96
+		goto err_imgdownload;
126
 	}
97
 	}
127
 
98
 
128
-	image_put ( image );
99
+	/* Free command line */
100
+	free ( cmdline );
101
+
129
 	return 0;
102
 	return 0;
103
+
104
+ err_imgdownload:
105
+	free ( cmdline );
106
+ err_cmdline:
107
+ err_parse_options:
108
+	return rc;
130
 }
109
 }
131
 
110
 
132
 /**
111
 /**
138
  */
117
  */
139
 static int imgfetch_exec ( int argc, char **argv ) {
118
 static int imgfetch_exec ( int argc, char **argv ) {
140
 
119
 
141
-	return imgfetch_core_exec ( argc, argv, &imgfetch_cmd,
142
-				    register_image );
120
+	return imgfetch_core_exec ( argc, argv, "fetch",
121
+				    register_and_put_image );
143
 }
122
 }
144
 
123
 
145
 /**
124
 /**
151
  */
130
  */
152
 static int kernel_exec ( int argc, char **argv ) {
131
 static int kernel_exec ( int argc, char **argv ) {
153
 
132
 
154
-	return imgfetch_core_exec ( argc, argv, &imgfetch_cmd,
133
+	return imgfetch_core_exec ( argc, argv, "select",
155
 				    register_and_select_image );
134
 				    register_and_select_image );
156
 }
135
 }
157
 
136
 
164
  */
143
  */
165
 static int chain_exec ( int argc, char **argv) {
144
 static int chain_exec ( int argc, char **argv) {
166
 
145
 
167
-	return imgfetch_core_exec ( argc, argv, &imgfetch_cmd,
146
+	return imgfetch_core_exec ( argc, argv, "boot",
168
 				    register_and_boot_image );
147
 				    register_and_boot_image );
169
 }
148
 }
170
 
149
 
230
 static int imgargs_exec ( int argc, char **argv ) {
209
 static int imgargs_exec ( int argc, char **argv ) {
231
 	struct imgargs_options opts;
210
 	struct imgargs_options opts;
232
 	struct image *image;
211
 	struct image *image;
212
+	char *cmdline = NULL;
233
 	int rc;
213
 	int rc;
234
 
214
 
235
 	/* Parse options */
215
 	/* Parse options */
236
 	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
216
 	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
237
-		return rc;
217
+		goto err_parse_options;
238
 
218
 
239
 	/* Parse image name */
219
 	/* Parse image name */
240
 	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
220
 	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
241
-		return rc;
221
+		goto err_parse_image;
222
+
223
+	/* Parse command line */
224
+	if ( argv[ optind + 1 ] != NULL ) {
225
+		cmdline = concat_args ( &argv[ optind + 1 ] );
226
+		if ( ! cmdline ) {
227
+			rc = -ENOMEM;
228
+			goto err_cmdline;
229
+		}
230
+	}
242
 
231
 
243
-	/* Fill in command line */
244
-	if ( ( rc = imgfill_cmdline ( image, &argv[ optind + 1 ] ) ) != 0 )
245
-		return rc;
232
+	/* Set command line */
233
+	if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 )
234
+		goto err_set_cmdline;
235
+
236
+	/* Free command line */
237
+	free ( cmdline );
246
 
238
 
247
 	return 0;
239
 	return 0;
240
+
241
+ err_set_cmdline:
242
+	free ( cmdline );
243
+ err_cmdline:
244
+ err_parse_image:
245
+ err_parse_options:
246
+	return rc;
248
 }
247
 }
249
 
248
 
250
 /** "imgexec" options */
249
 /** "imgexec" options */

+ 5
- 1
src/include/ipxe/image.h View File

58
 	struct image *replacement;
58
 	struct image *replacement;
59
 };
59
 };
60
 
60
 
61
+/** Image is registered */
62
+#define IMAGE_REGISTERED 0x00001
63
+
61
 /** Image is selected for execution */
64
 /** Image is selected for execution */
62
-#define IMAGE_SELECTED 0x0001
65
+#define IMAGE_SELECTED 0x0002
63
 
66
 
64
 /** An executable image type */
67
 /** An executable image type */
65
 struct image_type {
68
 struct image_type {
142
 struct image * find_image ( const char *name );
145
 struct image * find_image ( const char *name );
143
 extern int image_probe ( struct image *image );
146
 extern int image_probe ( struct image *image );
144
 extern int image_exec ( struct image *image );
147
 extern int image_exec ( struct image *image );
148
+extern int image_replace ( struct image *replacement );
145
 extern int image_select ( struct image *image );
149
 extern int image_select ( struct image *image );
146
 extern struct image * image_find_selected ( void );
150
 extern struct image * image_find_selected ( void );
147
 
151
 

+ 7
- 3
src/include/usr/imgmgmt.h View File

11
 
11
 
12
 #include <ipxe/image.h>
12
 #include <ipxe/image.h>
13
 
13
 
14
+extern int register_and_put_image ( struct image *image );
15
+extern int register_and_probe_image ( struct image *image );
14
 extern int register_and_select_image ( struct image *image );
16
 extern int register_and_select_image ( struct image *image );
15
 extern int register_and_boot_image ( struct image *image );
17
 extern int register_and_boot_image ( struct image *image );
16
-extern int imgdownload ( struct image *image, struct uri *uri,
18
+extern int register_and_replace_image ( struct image *image );
19
+extern int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
17
 			 int ( * action ) ( struct image *image ) );
20
 			 int ( * action ) ( struct image *image ) );
18
-extern int imgfetch ( struct image *image, const char *uri_string,
19
-		      int ( * action ) ( struct image *image ) );
21
+extern int imgdownload_string ( const char *uri_string, const char *name,
22
+				const char *cmdline,
23
+				int ( * action ) ( struct image *image ) );
20
 extern void imgstat ( struct image *image );
24
 extern void imgstat ( struct image *image );
21
 extern void imgfree ( struct image *image );
25
 extern void imgfree ( struct image *image );
22
 
26
 

+ 1
- 12
src/usr/autoboot.c View File

122
  * @ret rc		Return status code
122
  * @ret rc		Return status code
123
  */
123
  */
124
 int uriboot ( struct uri *filename, struct uri *root_path ) {
124
 int uriboot ( struct uri *filename, struct uri *root_path ) {
125
-	struct image *image;
126
 	int drive;
125
 	int drive;
127
 	int rc;
126
 	int rc;
128
 
127
 
129
-	/* Allocate image */
130
-	image = alloc_image();
131
-	if ( ! image ) {
132
-		printf ( "Could not allocate image\n" );
133
-		rc = -ENOMEM;
134
-		goto err_alloc_image;
135
-	}
136
-
137
 	/* Treat empty URIs as absent */
128
 	/* Treat empty URIs as absent */
138
 	if ( filename && ( ! uri_has_path ( filename ) ) )
129
 	if ( filename && ( ! uri_has_path ( filename ) ) )
139
 		filename = NULL;
130
 		filename = NULL;
183
 
174
 
184
 	/* Attempt filename boot if applicable */
175
 	/* Attempt filename boot if applicable */
185
 	if ( filename ) {
176
 	if ( filename ) {
186
-		if ( ( rc = imgdownload ( image, filename,
177
+		if ( ( rc = imgdownload ( filename, NULL, NULL,
187
 					  register_and_boot_image ) ) != 0 ) {
178
 					  register_and_boot_image ) ) != 0 ) {
188
 			printf ( "\nCould not chain image: %s\n",
179
 			printf ( "\nCould not chain image: %s\n",
189
 				 strerror ( rc ) );
180
 				 strerror ( rc ) );
229
 	}
220
 	}
230
  err_san_hook:
221
  err_san_hook:
231
  err_no_boot:
222
  err_no_boot:
232
-	image_put ( image );
233
- err_alloc_image:
234
 	return rc;
223
 	return rc;
235
 }
224
 }
236
 
225
 

+ 91
- 13
src/usr/imgmgmt.c View File

36
  */
36
  */
37
 
37
 
38
 /**
38
 /**
39
- * Register and select an image
39
+ * Register an image and leave it registered
40
  *
40
  *
41
  * @v image		Executable image
41
  * @v image		Executable image
42
  * @ret rc		Return status code
42
  * @ret rc		Return status code
43
+ *
44
+ * This function assumes an ownership of the passed image.
43
  */
45
  */
44
-int register_and_select_image ( struct image *image ) {
46
+int register_and_put_image ( struct image *image ) {
47
+	int rc;
48
+
49
+	rc = register_image ( image );
50
+	image_put ( image );
51
+	return rc;
52
+}
53
+
54
+/**
55
+ * Register and probe an image
56
+ *
57
+ * @v image		Executable image
58
+ * @ret rc		Return status code
59
+ *
60
+ * This function assumes an ownership of the passed image.
61
+ */
62
+int register_and_probe_image ( struct image *image ) {
45
 	int rc;
63
 	int rc;
46
 
64
 
47
-	if ( ( rc = register_image ( image ) ) != 0 )
65
+	if ( ( rc = register_and_put_image ( image ) ) != 0 )
48
 		return rc;
66
 		return rc;
49
 
67
 
50
 	if ( ( rc = image_probe ( image ) ) != 0 )
68
 	if ( ( rc = image_probe ( image ) ) != 0 )
51
 		return rc;
69
 		return rc;
52
 
70
 
71
+	return 0;
72
+}
73
+
74
+/**
75
+ * Register and select an image
76
+ *
77
+ * @v image		Executable image
78
+ * @ret rc		Return status code
79
+ *
80
+ * This function assumes an ownership of the passed image.
81
+ */
82
+int register_and_select_image ( struct image *image ) {
83
+	int rc;
84
+
85
+	if ( ( rc = register_and_probe_image ( image ) ) != 0 )
86
+		return rc;
87
+
53
 	if ( ( rc = image_select ( image ) ) != 0 )
88
 	if ( ( rc = image_select ( image ) ) != 0 )
54
 		return rc;
89
 		return rc;
55
 
90
 
61
  *
96
  *
62
  * @v image		Image
97
  * @v image		Image
63
  * @ret rc		Return status code
98
  * @ret rc		Return status code
99
+ *
100
+ * This function assumes an ownership of the passed image.
64
  */
101
  */
65
 int register_and_boot_image ( struct image *image ) {
102
 int register_and_boot_image ( struct image *image ) {
66
 	int rc;
103
 	int rc;
75
 }
112
 }
76
 
113
 
77
 /**
114
 /**
78
- * Download an image
115
+ * Register and replace image
79
  *
116
  *
80
  * @v image		Image
117
  * @v image		Image
118
+ * @ret rc		Return status code
119
+ *
120
+ * This function assumes an ownership of the passed image.
121
+ */
122
+int register_and_replace_image ( struct image *image ) {
123
+	int rc;
124
+
125
+	if ( ( rc = register_and_probe_image ( image ) ) != 0 )
126
+		return rc;
127
+
128
+	if ( ( rc = image_replace ( image ) ) != 0 )
129
+		return rc;
130
+
131
+	return 0;
132
+}
133
+
134
+/**
135
+ * Download an image
136
+ *
81
  * @v uri		URI
137
  * @v uri		URI
138
+ * @v name		Image name, or NULL to use default
139
+ * @v cmdline		Command line, or NULL for no command line
82
  * @v action		Action to take upon a successful download
140
  * @v action		Action to take upon a successful download
83
  * @ret rc		Return status code
141
  * @ret rc		Return status code
84
  */
142
  */
85
-int imgdownload ( struct image *image, struct uri *uri,
143
+int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
86
 		  int ( * action ) ( struct image *image ) ) {
144
 		  int ( * action ) ( struct image *image ) ) {
145
+	struct image *image;
87
 	size_t len = ( unparse_uri ( NULL, 0, uri, URI_ALL ) + 1 );
146
 	size_t len = ( unparse_uri ( NULL, 0, uri, URI_ALL ) + 1 );
88
 	char uri_string_redacted[len];
147
 	char uri_string_redacted[len];
89
 	const char *password;
148
 	const char *password;
90
 	int rc;
149
 	int rc;
91
 
150
 
151
+	/* Allocate image */
152
+	image = alloc_image();
153
+	if ( ! image )
154
+		return -ENOMEM;
155
+
156
+	/* Set image name */
157
+	image_set_name ( image, name );
158
+
92
 	/* Set image URI */
159
 	/* Set image URI */
93
 	image_set_uri ( image, uri );
160
 	image_set_uri ( image, uri );
94
 
161
 
162
+	/* Set image command line */
163
+	image_set_cmdline ( image, cmdline );
164
+
95
 	/* Redact password portion of URI, if necessary */
165
 	/* Redact password portion of URI, if necessary */
96
 	password = uri->password;
166
 	password = uri->password;
97
 	if ( password )
167
 	if ( password )
102
 
172
 
103
 	/* Create downloader */
173
 	/* Create downloader */
104
 	if ( ( rc = create_downloader ( &monojob, image, LOCATION_URI,
174
 	if ( ( rc = create_downloader ( &monojob, image, LOCATION_URI,
105
-					uri ) ) != 0 )
175
+					uri ) ) != 0 ) {
176
+		image_put ( image );
106
 		return rc;
177
 		return rc;
178
+	}
107
 
179
 
108
 	/* Wait for download to complete */
180
 	/* Wait for download to complete */
109
-	if ( ( rc = monojob_wait ( uri_string_redacted ) ) != 0 )
181
+	if ( ( rc = monojob_wait ( uri_string_redacted ) ) != 0 ) {
182
+		image_put ( image );
110
 		return rc;
183
 		return rc;
184
+	}
111
 
185
 
112
-	/* Act upon downloaded image */
186
+	/* Act upon downloaded image.  This action assumes our
187
+	 * ownership of the image.
188
+	 */
113
 	if ( ( rc = action ( image ) ) != 0 )
189
 	if ( ( rc = action ( image ) ) != 0 )
114
 		return rc;
190
 		return rc;
115
 
191
 
117
 }
193
 }
118
 
194
 
119
 /**
195
 /**
120
- * Fetch an image
196
+ * Download an image
121
  *
197
  *
122
- * @v image		Image
123
  * @v uri_string	URI as a string (e.g. "http://www.nowhere.com/vmlinuz")
198
  * @v uri_string	URI as a string (e.g. "http://www.nowhere.com/vmlinuz")
199
+ * @v name		Image name, or NULL to use default
200
+ * @v cmdline		Command line, or NULL for no command line
124
  * @v action		Action to take upon a successful download
201
  * @v action		Action to take upon a successful download
125
  * @ret rc		Return status code
202
  * @ret rc		Return status code
126
  */
203
  */
127
-int imgfetch ( struct image *image, const char *uri_string,
128
-	       int ( * action ) ( struct image *image ) ) {
204
+int imgdownload_string ( const char *uri_string, const char *name,
205
+			 const char *cmdline,
206
+			 int ( * action ) ( struct image *image ) ) {
129
 	struct uri *uri;
207
 	struct uri *uri;
130
 	int rc;
208
 	int rc;
131
 
209
 
132
 	if ( ! ( uri = parse_uri ( uri_string ) ) )
210
 	if ( ! ( uri = parse_uri ( uri_string ) ) )
133
 		return -ENOMEM;
211
 		return -ENOMEM;
134
 
212
 
135
-	rc = imgdownload ( image, uri, action );
213
+	rc = imgdownload ( uri, name, cmdline, action );
136
 
214
 
137
 	uri_put ( uri );
215
 	uri_put ( uri );
138
 	return rc;
216
 	return rc;

Loading…
Cancel
Save