Переглянути джерело

[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 роки тому
джерело
коміт
9fa4ac2e9a

+ 3
- 4
src/arch/i386/image/com32.c Переглянути файл

@@ -132,10 +132,9 @@ static int com32_exec_loop ( struct image *image ) {
132 132
 		break;
133 133
 
134 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 138
 		break;
140 139
 
141 140
 	case COMBOOT_EXIT_COMMAND:

+ 3
- 4
src/arch/i386/image/comboot.c Переглянути файл

@@ -188,10 +188,9 @@ static int comboot_exec_loop ( struct image *image ) {
188 188
 		break;
189 189
 
190 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 194
 		break;
196 195
 
197 196
 	case COMBOOT_EXIT_COMMAND:

+ 0
- 3
src/arch/i386/include/comboot.h Переглянути файл

@@ -161,9 +161,6 @@ extern int comboot_resolv ( const char *name, struct in_addr *address );
161 161
 /* setjmp/longjmp context buffer used to return after loading an image */
162 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 164
 extern void *com32_external_esp;
168 165
 
169 166
 #define COMBOOT_EXIT 1

+ 8
- 41
src/arch/i386/interface/syslinux/comboot_call.c Переглянути файл

@@ -81,9 +81,6 @@ extern void int22_wrapper ( void );
81 81
 /* setjmp/longjmp context buffer used to return after loading an image */
82 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 84
 /* Mode flags set by INT 22h AX=0017h */
88 85
 static uint16_t comboot_graphics_mode = 0;
89 86
 
@@ -169,8 +166,6 @@ void comboot_force_text_mode ( void ) {
169 166
  * Fetch kernel and optional initrd
170 167
  */
171 168
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
172
-	struct image *kernel = NULL;
173
-	struct image *initrd = NULL;
174 169
 	char *initrd_file;
175 170
 	int rc;
176 171
 
@@ -188,18 +183,12 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
188 183
 
189 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 189
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
201 190
 			      strerror ( rc ) );
202
-			goto out;
191
+			return rc;
203 192
 		}
204 193
 
205 194
 		/* Restore space after initrd name, if applicable */
@@ -210,36 +199,14 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
210 199
 	DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
211 200
 
212 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 204
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
222 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 Переглянути файл

@@ -130,6 +130,7 @@ int register_image ( struct image *image ) {
130 130
 
131 131
 	/* Add to image list */
132 132
 	image_get ( image );
133
+	image->flags |= IMAGE_REGISTERED;
133 134
 	list_add_tail ( &image->list, &images );
134 135
 	DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n",
135 136
 	       image->name, user_to_phys ( image->data, 0 ),
@@ -144,8 +145,10 @@ int register_image ( struct image *image ) {
144 145
  * @v image		Executable image
145 146
  */
146 147
 void unregister_image ( struct image *image ) {
148
+
147 149
 	DBGC ( image, "IMAGE %s unregistered\n", image->name );
148 150
 	list_del ( &image->list );
151
+	image->flags &= ~IMAGE_REGISTERED;
149 152
 	image_put ( image );
150 153
 }
151 154
 
@@ -201,6 +204,10 @@ int image_probe ( struct image *image ) {
201 204
  *
202 205
  * @v image		Executable image
203 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 212
 int image_exec ( struct image *image ) {
206 213
 	struct image *saved_current_image;
@@ -208,6 +215,9 @@ int image_exec ( struct image *image ) {
208 215
 	struct uri *old_cwuri;
209 216
 	int rc;
210 217
 
218
+	/* Sanity check */
219
+	assert ( image->flags & IMAGE_REGISTERED );
220
+
211 221
 	/* Check that this image can be executed */
212 222
 	if ( ( rc = image_probe ( image ) ) != 0 )
213 223
 		return rc;
@@ -233,9 +243,13 @@ int image_exec ( struct image *image ) {
233 243
 	}
234 244
 
235 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 250
 	replacement = image->replacement;
251
+	if ( replacement )
252
+		assert ( replacement->flags & IMAGE_REGISTERED );
239 253
 
240 254
 	/* Drop temporary reference to the original image */
241 255
 	image_put ( image );
@@ -258,6 +272,41 @@ int image_exec ( struct image *image ) {
258 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 311
  * Select image for execution
263 312
  *

+ 55
- 56
src/hci/commands/image_cmd.c Переглянути файл

@@ -35,30 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
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 38
 /** "imgfetch" options */
63 39
 struct imgfetch_options {
64 40
 	/** Image name */
@@ -82,51 +58,54 @@ static struct command_descriptor imgfetch_cmd =
82 58
  * @v argc		Argument count
83 59
  * @v argv		Argument list
84 60
  * @v cmd		Command descriptor
61
+ * @v action_name	Action name (for error messages)
85 62
  * @v action		Action to take upon a successful download
86 63
  * @ret rc		Return status code
87 64
  */
88 65
 static int imgfetch_core_exec ( int argc, char **argv,
89
-				struct command_descriptor *cmd,
66
+				const char *action_name,
90 67
 				int ( * action ) ( struct image *image ) ) {
91 68
 	struct imgfetch_options opts;
92
-	struct image *image;
93 69
 	char *uri_string;
70
+	char *cmdline = NULL;
94 71
 	int rc;
95 72
 
96 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 77
 	/* Parse URI string */
101 78
 	uri_string = argv[optind];
102 79
 	if ( ! opts.name )
103 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 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 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,8 +117,8 @@ static int imgfetch_core_exec ( int argc, char **argv,
138 117
  */
139 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,7 +130,7 @@ static int imgfetch_exec ( int argc, char **argv ) {
151 130
  */
152 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 134
 				    register_and_select_image );
156 135
 }
157 136
 
@@ -164,7 +143,7 @@ static int kernel_exec ( int argc, char **argv ) {
164 143
  */
165 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 147
 				    register_and_boot_image );
169 148
 }
170 149
 
@@ -230,21 +209,41 @@ static struct command_descriptor imgargs_cmd =
230 209
 static int imgargs_exec ( int argc, char **argv ) {
231 210
 	struct imgargs_options opts;
232 211
 	struct image *image;
212
+	char *cmdline = NULL;
233 213
 	int rc;
234 214
 
235 215
 	/* Parse options */
236 216
 	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
237
-		return rc;
217
+		goto err_parse_options;
238 218
 
239 219
 	/* Parse image name */
240 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 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 249
 /** "imgexec" options */

+ 5
- 1
src/include/ipxe/image.h Переглянути файл

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

+ 7
- 3
src/include/usr/imgmgmt.h Переглянути файл

@@ -11,12 +11,16 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 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 16
 extern int register_and_select_image ( struct image *image );
15 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 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 24
 extern void imgstat ( struct image *image );
21 25
 extern void imgfree ( struct image *image );
22 26
 

+ 1
- 12
src/usr/autoboot.c Переглянути файл

@@ -122,18 +122,9 @@ struct setting skip_san_boot_setting __setting = {
122 122
  * @ret rc		Return status code
123 123
  */
124 124
 int uriboot ( struct uri *filename, struct uri *root_path ) {
125
-	struct image *image;
126 125
 	int drive;
127 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 128
 	/* Treat empty URIs as absent */
138 129
 	if ( filename && ( ! uri_has_path ( filename ) ) )
139 130
 		filename = NULL;
@@ -183,7 +174,7 @@ int uriboot ( struct uri *filename, struct uri *root_path ) {
183 174
 
184 175
 	/* Attempt filename boot if applicable */
185 176
 	if ( filename ) {
186
-		if ( ( rc = imgdownload ( image, filename,
177
+		if ( ( rc = imgdownload ( filename, NULL, NULL,
187 178
 					  register_and_boot_image ) ) != 0 ) {
188 179
 			printf ( "\nCould not chain image: %s\n",
189 180
 				 strerror ( rc ) );
@@ -229,8 +220,6 @@ int uriboot ( struct uri *filename, struct uri *root_path ) {
229 220
 	}
230 221
  err_san_hook:
231 222
  err_no_boot:
232
-	image_put ( image );
233
- err_alloc_image:
234 223
 	return rc;
235 224
 }
236 225
 

+ 91
- 13
src/usr/imgmgmt.c Переглянути файл

@@ -36,20 +36,55 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 36
  */
37 37
 
38 38
 /**
39
- * Register and select an image
39
+ * Register an image and leave it registered
40 40
  *
41 41
  * @v image		Executable image
42 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 63
 	int rc;
46 64
 
47
-	if ( ( rc = register_image ( image ) ) != 0 )
65
+	if ( ( rc = register_and_put_image ( image ) ) != 0 )
48 66
 		return rc;
49 67
 
50 68
 	if ( ( rc = image_probe ( image ) ) != 0 )
51 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 88
 	if ( ( rc = image_select ( image ) ) != 0 )
54 89
 		return rc;
55 90
 
@@ -61,6 +96,8 @@ int register_and_select_image ( struct image *image ) {
61 96
  *
62 97
  * @v image		Image
63 98
  * @ret rc		Return status code
99
+ *
100
+ * This function assumes an ownership of the passed image.
64 101
  */
65 102
 int register_and_boot_image ( struct image *image ) {
66 103
 	int rc;
@@ -75,23 +112,56 @@ int register_and_boot_image ( struct image *image ) {
75 112
 }
76 113
 
77 114
 /**
78
- * Download an image
115
+ * Register and replace image
79 116
  *
80 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 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 140
  * @v action		Action to take upon a successful download
83 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 144
 		  int ( * action ) ( struct image *image ) ) {
145
+	struct image *image;
87 146
 	size_t len = ( unparse_uri ( NULL, 0, uri, URI_ALL ) + 1 );
88 147
 	char uri_string_redacted[len];
89 148
 	const char *password;
90 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 159
 	/* Set image URI */
93 160
 	image_set_uri ( image, uri );
94 161
 
162
+	/* Set image command line */
163
+	image_set_cmdline ( image, cmdline );
164
+
95 165
 	/* Redact password portion of URI, if necessary */
96 166
 	password = uri->password;
97 167
 	if ( password )
@@ -102,14 +172,20 @@ int imgdownload ( struct image *image, struct uri *uri,
102 172
 
103 173
 	/* Create downloader */
104 174
 	if ( ( rc = create_downloader ( &monojob, image, LOCATION_URI,
105
-					uri ) ) != 0 )
175
+					uri ) ) != 0 ) {
176
+		image_put ( image );
106 177
 		return rc;
178
+	}
107 179
 
108 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 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 189
 	if ( ( rc = action ( image ) ) != 0 )
114 190
 		return rc;
115 191
 
@@ -117,22 +193,24 @@ int imgdownload ( struct image *image, struct uri *uri,
117 193
 }
118 194
 
119 195
 /**
120
- * Fetch an image
196
+ * Download an image
121 197
  *
122
- * @v image		Image
123 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 201
  * @v action		Action to take upon a successful download
125 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 207
 	struct uri *uri;
130 208
 	int rc;
131 209
 
132 210
 	if ( ! ( uri = parse_uri ( uri_string ) ) )
133 211
 		return -ENOMEM;
134 212
 
135
-	rc = imgdownload ( image, uri, action );
213
+	rc = imgdownload ( uri, name, cmdline, action );
136 214
 
137 215
 	uri_put ( uri );
138 216
 	return rc;

Завантаження…
Відмінити
Зберегти