Bladeren bron

[image] Simplify image management commands and internal API

Remove the name, cmdline, and action parameters from imgdownload() and
imgdownload_string().  These functions now simply download and return
an image.

Add the function imgacquire(), which will interpret a "name or URI
string" parameter and return either an existing image or a newly
downloaded image.

Use imgacquire() to merge similar image-management commands that
currently differ only by whether they take the name of an existing
image or the URI of a new image to download.  For example, "chain" and
"imgexec" can now be merged.

Extend imgstat and imgfree commands to take an optional list of
images.

Remove the arbitrary restriction on the length of image names.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 jaren geleden
bovenliggende
commit
1c127a6962

+ 7
- 2
src/arch/i386/core/runtime.c Bestand weergeven

@@ -189,14 +189,18 @@ static int initrd_init ( void ) {
189 189
 	       initrd_phys, ( initrd_phys + initrd_len ) );
190 190
 
191 191
 	/* Allocate image */
192
-	image = alloc_image();
192
+	image = alloc_image ( NULL );
193 193
 	if ( ! image ) {
194 194
 		DBGC ( colour, "RUNTIME could not allocate image for "
195 195
 		       "initrd\n" );
196 196
 		rc = -ENOMEM;
197 197
 		goto err_alloc_image;
198 198
 	}
199
-	image_set_name ( image, "<INITRD>" );
199
+	if ( ( rc = image_set_name ( image, "<INITRD>" ) ) != 0 ) {
200
+		DBGC ( colour, "RUNTIME could not set image name: %s\n",
201
+		       strerror ( rc ) );
202
+		goto err_set_name;
203
+	}
200 204
 
201 205
 	/* Allocate and copy initrd content */
202 206
 	image->data = umalloc ( initrd_len );
@@ -227,6 +231,7 @@ static int initrd_init ( void ) {
227 231
 
228 232
  err_register_image:
229 233
  err_umalloc:
234
+ err_set_name:
230 235
 	image_put ( image );
231 236
  err_alloc_image:
232 237
 	return rc;

+ 12
- 5
src/arch/i386/interface/syslinux/comboot_call.c Bestand weergeven

@@ -166,6 +166,8 @@ void comboot_force_text_mode ( void ) {
166 166
  * Fetch kernel and optional initrd
167 167
  */
168 168
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
169
+	struct image *kernel;
170
+	struct image *initrd;
169 171
 	char *initrd_file;
170 172
 	int rc;
171 173
 
@@ -184,8 +186,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
184 186
 		DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file );
185 187
 
186 188
 		/* Fetch initrd */
187
-		if ( ( rc = imgdownload_string ( initrd_file, NULL, NULL,
188
-						 NULL ) ) != 0 ) {
189
+		if ( ( rc = imgdownload_string ( initrd_file, &initrd ) ) != 0){
189 190
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
190 191
 			      strerror ( rc ) );
191 192
 			return rc;
@@ -198,14 +199,20 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
198 199
 
199 200
 	DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
200 201
 
201
-	/* Allocate and fetch kernel */
202
-	if ( ( rc = imgdownload_string ( kernel_file, NULL, cmdline,
203
-					 image_replace ) ) != 0 ) {
202
+	/* Fetch kernel */
203
+	if ( ( rc = imgdownload_string ( kernel_file, &kernel ) ) != 0 ) {
204 204
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
205 205
 		      strerror ( rc ) );
206 206
 		return rc;
207 207
 	}
208 208
 
209
+	/* Replace comboot image with kernel */
210
+	if ( ( rc = image_replace ( kernel ) ) != 0 ) {
211
+		DBG ( "COMBOOT: could not replace with kernel: %s\n",
212
+		      strerror ( rc ) );
213
+		return rc;
214
+	}
215
+
209 216
 	return 0;
210 217
 }
211 218
 

+ 42
- 19
src/core/image.c Bestand weergeven

@@ -66,6 +66,7 @@ static int require_trusted_images_permanent = 0;
66 66
 static void free_image ( struct refcnt *refcnt ) {
67 67
 	struct image *image = container_of ( refcnt, struct image, refcnt );
68 68
 
69
+	free ( image->name );
69 70
 	free ( image->cmdline );
70 71
 	uri_put ( image->uri );
71 72
 	ufree ( image->data );
@@ -77,37 +78,56 @@ static void free_image ( struct refcnt *refcnt ) {
77 78
 /**
78 79
  * Allocate executable image
79 80
  *
81
+ * @v uri		URI, or NULL
80 82
  * @ret image		Executable image
81 83
  */
82
-struct image * alloc_image ( void ) {
84
+struct image * alloc_image ( struct uri *uri ) {
85
+	const char *name;
83 86
 	struct image *image;
87
+	int rc;
84 88
 
89
+	/* Allocate image */
85 90
 	image = zalloc ( sizeof ( *image ) );
86
-	if ( image ) {
87
-		ref_init ( &image->refcnt, free_image );
91
+	if ( ! image )
92
+		goto err_alloc;
93
+
94
+	/* Initialise image */
95
+	ref_init ( &image->refcnt, free_image );
96
+	if ( uri ) {
97
+		image->uri = uri_get ( uri );
98
+		name = basename ( ( char * ) uri->path );
99
+		if ( ( rc = image_set_name ( image, name ) ) != 0 )
100
+			goto err_set_name;
88 101
 	}
102
+
89 103
 	return image;
104
+
105
+ err_set_name:
106
+	image_put ( image );
107
+ err_alloc:
108
+	return NULL;
90 109
 }
91 110
 
92 111
 /**
93
- * Set image URI
112
+ * Set image name
94 113
  *
95 114
  * @v image		Image
96
- * @v URI		New image URI
97
- *
98
- * If no name is set, the name will be updated to the base name of the
99
- * URI path (if any).
115
+ * @v name		New image name
116
+ * @ret rc		Return status code
100 117
  */
101
-void image_set_uri ( struct image *image, struct uri *uri ) {
102
-	const char *path = uri->path;
118
+int image_set_name ( struct image *image, const char *name ) {
119
+	char *name_copy;
103 120
 
104
-	/* Replace URI reference */
105
-	uri_put ( image->uri );
106
-	image->uri = uri_get ( uri );
121
+	/* Duplicate name */
122
+	name_copy = strdup ( name );
123
+	if ( ! name_copy )
124
+		return -ENOMEM;
125
+
126
+	/* Replace existing name */
127
+	free ( image->name );
128
+	image->name = name_copy;
107 129
 
108
-	/* Set name if none already specified */
109
-	if ( path && ( ! image->name[0] ) )
110
-		image_set_name ( image, basename ( ( char * ) path ) );
130
+	return 0;
111 131
 }
112 132
 
113 133
 /**
@@ -137,11 +157,14 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
137 157
  */
138 158
 int register_image ( struct image *image ) {
139 159
 	static unsigned int imgindex = 0;
160
+	char name[8]; /* "imgXXXX" */
161
+	int rc;
140 162
 
141 163
 	/* Create image name if it doesn't already have one */
142
-	if ( ! image->name[0] ) {
143
-		snprintf ( image->name, sizeof ( image->name ), "img%d",
144
-			   imgindex++ );
164
+	if ( ! image->name ) {
165
+		snprintf ( name, sizeof ( name ), "img%d", imgindex++ );
166
+		if ( ( rc = image_set_name ( image, name ) ) != 0 )
167
+			return rc;
145 168
 	}
146 169
 
147 170
 	/* Avoid ending up with multiple "selected" images on

+ 0
- 22
src/core/parseopt.c Bestand weergeven

@@ -114,28 +114,6 @@ int parse_netdev ( const char *text, struct net_device **netdev ) {
114 114
 	return 0;
115 115
 }
116 116
 
117
-/**
118
- * Parse image name
119
- *
120
- * @v text		Text
121
- * @ret image		Image
122
- * @ret rc		Return status code
123
- */
124
-int parse_image ( const char *text, struct image **image ) {
125
-
126
-	/* Sanity check */
127
-	assert ( text != NULL );
128
-
129
-	/* Find network device */
130
-	*image = find_image ( text );
131
-	if ( ! *image ) {
132
-		printf ( "\"%s\": no such image\n", text );
133
-		return -ENOENT;
134
-	}
135
-
136
-	return 0;
137
-}
138
-
139 117
 /**
140 118
  * Parse flag
141 119
  *

+ 3
- 2
src/hci/commands/digest_cmd.c Bestand weergeven

@@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
28 28
 #include <ipxe/crypto.h>
29 29
 #include <ipxe/md5.h>
30 30
 #include <ipxe/sha1.h>
31
+#include <usr/imgmgmt.h>
31 32
 
32 33
 /** @file
33 34
  *
@@ -74,8 +75,8 @@ static int digest_exec ( int argc, char **argv,
74 75
 
75 76
 	for ( i = optind ; i < argc ; i++ ) {
76 77
 
77
-		/* find image */
78
-		if ( ( rc = parse_image ( argv[i], &image ) ) != 0 )
78
+		/* Acquire image */
79
+		if ( ( rc = imgacquire ( argv[i], &image ) ) != 0 )
79 80
 			continue;
80 81
 		offset = 0;
81 82
 		len = image->len;

+ 170
- 223
src/hci/commands/image_cmd.c Bestand weergeven

@@ -34,164 +34,201 @@ FILE_LICENCE ( GPL2_OR_LATER );
34 34
  *
35 35
  */
36 36
 
37
-/** "imgfetch" options */
38
-struct imgfetch_options {
37
+/** "img{single}" options */
38
+struct imgsingle_options {
39 39
 	/** Image name */
40 40
 	const char *name;
41 41
 };
42 42
 
43
-/** "imgfetch" option list */
44
-static struct option_descriptor imgfetch_opts[] = {
43
+/** "img{single}" option list */
44
+static struct option_descriptor imgsingle_opts[] = {
45 45
 	OPTION_DESC ( "name", 'n', required_argument,
46
-		      struct imgfetch_options, name, parse_string ),
46
+		      struct imgsingle_options, name, parse_string ),
47 47
 };
48 48
 
49
-/** "imgfetch" command descriptor */
50
-static struct command_descriptor imgfetch_cmd =
51
-	COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
52
-		       "[--name <name>] <uri> [<arguments>...]" );
49
+/** "img{single}" command descriptor */
50
+static struct command_descriptor imgsingle_cmd =
51
+	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
52
+		       1, MAX_ARGUMENTS,
53
+		       "[--name <name>] <uri|image> [<arguments>...]" );
54
+
55
+/** An "img{single}" family command descriptor */
56
+struct imgsingle_descriptor {
57
+	/** Command descriptor */
58
+	struct command_descriptor *cmd;
59
+	/** Function to use to acquire the image */
60
+	int ( * acquire ) ( const char *name, struct image **image );
61
+	/** Pre-action to take upon image, or NULL */
62
+	void ( * preaction ) ( struct image *image );
63
+	/** Action to take upon image, or NULL */
64
+	int ( * action ) ( struct image *image );
65
+	/** Verb to describe action */
66
+	const char *verb;
67
+};
53 68
 
54 69
 /**
55
- * The "imgfetch" and friends command body
70
+ * The "img{single}" family of commands
56 71
  *
57 72
  * @v argc		Argument count
58 73
  * @v argv		Argument list
59
- * @v cmd		Command descriptor
74
+ * @v desc		"img{single}" command descriptor
60 75
  * @v action_name	Action name (for error messages)
61
- * @v action		Action to take upon a successful download
76
+ * @v action		Action to take upon image
62 77
  * @ret rc		Return status code
63 78
  */
64
-static int imgfetch_core_exec ( int argc, char **argv,
65
-				const char *action_name,
66
-				int ( * action ) ( struct image *image ) ) {
67
-	struct imgfetch_options opts;
68
-	char *uri_string;
79
+static int imgsingle_exec ( int argc, char **argv,
80
+			    struct imgsingle_descriptor *desc ) {
81
+	struct imgsingle_options opts;
82
+	char *name_uri = NULL;
69 83
 	char *cmdline = NULL;
84
+	struct image *image;
70 85
 	int rc;
71 86
 
72 87
 	/* Parse options */
73
-	if ( ( rc = parse_options ( argc, argv, &imgfetch_cmd, &opts ) ) != 0 )
88
+	if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
74 89
 		goto err_parse_options;
75 90
 
76
-	/* Parse URI string */
77
-	uri_string = argv[optind];
91
+	/* Parse name/URI string and command line, if present */
92
+	if ( optind < argc ) {
93
+		name_uri = argv[optind];
94
+		if ( argv[ optind + 1 ] != NULL ) {
95
+			cmdline = concat_args ( &argv[ optind + 1 ] );
96
+			if ( ! cmdline ) {
97
+				rc = -ENOMEM;
98
+				goto err_parse_cmdline;
99
+			}
100
+		}
101
+	}
78 102
 
79
-	/* Parse command line */
80
-	if ( argv[ optind + 1 ] != NULL ) {
81
-		cmdline = concat_args ( &argv[ optind + 1 ] );
82
-		if ( ! cmdline ) {
83
-			rc = -ENOMEM;
84
-			goto err_cmdline;
103
+	/* Acquire the image */
104
+	if ( name_uri ) {
105
+		if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
106
+			goto err_acquire;
107
+	} else {
108
+		image = image_find_selected();
109
+		if ( ! image ) {
110
+			printf ( "No image selected\n" );
111
+			goto err_acquire;
85 112
 		}
86 113
 	}
87 114
 
88
-	/* Fetch the image */
89
-	if ( ( rc = imgdownload_string ( uri_string, opts.name, cmdline,
90
-					 action ) ) != 0 ) {
91
-		printf ( "Could not %s %s: %s\n",
92
-			 action_name, uri_string, strerror ( rc ) );
93
-		goto err_imgdownload;
115
+	/* Carry out command pre-action, if applicable */
116
+	if ( desc->preaction )
117
+		desc->preaction ( image );
118
+
119
+	/* Set the image name, if applicable */
120
+	if ( opts.name ) {
121
+		if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
122
+			printf ( "Could not name image: %s\n",
123
+				 strerror ( rc ) );
124
+			goto err_set_name;
125
+		}
94 126
 	}
95 127
 
96
-	/* Free command line */
97
-	free ( cmdline );
128
+	/* Set the command-line arguments, if applicable */
129
+	if ( cmdline ) {
130
+		if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
131
+			printf ( "Could not set arguments: %s\n",
132
+				 strerror ( rc ) );
133
+			goto err_set_cmdline;
134
+		}
135
+	}
98 136
 
99
-	return 0;
137
+	/* Carry out command action, if applicable */
138
+	if ( desc->action ) {
139
+		if ( ( rc = desc->action ( image ) ) != 0 ) {
140
+			printf ( "Could not %s: %s\n",
141
+				 desc->verb, strerror ( rc ) );
142
+			goto err_action;
143
+		}
144
+	}
100 145
 
101
- err_imgdownload:
146
+	/* Success */
147
+	rc = 0;
148
+
149
+ err_action:
150
+ err_set_cmdline:
151
+ err_set_name:
152
+ err_acquire:
102 153
 	free ( cmdline );
103
- err_cmdline:
154
+ err_parse_cmdline:
104 155
  err_parse_options:
105 156
 	return rc;
106 157
 }
107 158
 
108
-/**
109
- * The "imgfetch"/"module" command
110
- *
111
- * @v argc		Argument count
112
- * @v argv		Argument list
113
- * @ret rc		Return status code
114
- */
115
-static int imgfetch_exec ( int argc, char **argv ) {
159
+/** "imgfetch" command descriptor */
160
+static struct command_descriptor imgfetch_cmd =
161
+	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
162
+		       1, MAX_ARGUMENTS,
163
+		       "[--name <name>] <uri> [<arguments>...]" );
116 164
 
117
-	return imgfetch_core_exec ( argc, argv, "fetch", NULL );
118
-}
165
+/** "imgfetch" family command descriptor */
166
+struct imgsingle_descriptor imgfetch_desc = {
167
+	.cmd = &imgfetch_cmd,
168
+	.acquire = imgdownload_string,
169
+};
119 170
 
120 171
 /**
121
- * The "kernel" command
172
+ * The "imgfetch" command
122 173
  *
123 174
  * @v argc		Argument count
124 175
  * @v argv		Argument list
125 176
  * @ret rc		Return status code
126 177
  */
127
-static int kernel_exec ( int argc, char **argv ) {
128
-
129
-	return imgfetch_core_exec ( argc, argv, "select", image_select );
178
+static int imgfetch_exec ( int argc, char **argv ) {
179
+	return imgsingle_exec ( argc, argv, &imgfetch_desc );
130 180
 }
131 181
 
182
+/** "imgselect" family command descriptor */
183
+struct imgsingle_descriptor imgselect_desc = {
184
+	.cmd = &imgsingle_cmd,
185
+	.acquire = imgacquire,
186
+	.action = image_select,
187
+	.verb = "select",
188
+};
189
+
132 190
 /**
133
- * The "chain" command
191
+ * The "imgselect" command
134 192
  *
135 193
  * @v argc		Argument count
136 194
  * @v argv		Argument list
137 195
  * @ret rc		Return status code
138 196
  */
139
-static int chain_exec ( int argc, char **argv) {
140
-
141
-	return imgfetch_core_exec ( argc, argv, "boot", image_exec );
197
+static int imgselect_exec ( int argc, char **argv ) {
198
+	return imgsingle_exec ( argc, argv, &imgselect_desc );
142 199
 }
143 200
 
144
-/** "imgselect" options */
145
-struct imgselect_options {};
146
-
147
-/** "imgselect" option list */
148
-static struct option_descriptor imgselect_opts[] = {};
149
-
150
-/** "imgselect" command descriptor */
151
-static struct command_descriptor imgselect_cmd =
152
-	COMMAND_DESC ( struct imgselect_options, imgselect_opts, 1, 1,
153
-		       "<image>" );
201
+/** "imgexec" command descriptor */
202
+static struct command_descriptor imgexec_cmd =
203
+	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
204
+		       0, MAX_ARGUMENTS,
205
+		       "[--name <name>] [<uri|image> [<arguments>...]]" );
206
+
207
+/** "imgexec" family command descriptor */
208
+struct imgsingle_descriptor imgexec_desc = {
209
+	.cmd = &imgexec_cmd,
210
+	.acquire = imgacquire,
211
+	.action = image_exec,
212
+	.verb = "boot",
213
+};
154 214
 
155 215
 /**
156
- * The "imgselect" command
216
+ * The "imgexec" command
157 217
  *
158 218
  * @v argc		Argument count
159 219
  * @v argv		Argument list
160 220
  * @ret rc		Return status code
161 221
  */
162
-static int imgselect_exec ( int argc, char **argv ) {
163
-	struct imgselect_options opts;
164
-	struct image *image;
165
-	int rc;
166
-
167
-	/* Parse options */
168
-	if ( ( rc = parse_options ( argc, argv, &imgselect_cmd, &opts ) ) != 0 )
169
-		return rc;
170
-
171
-	/* Parse image name */
172
-	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
173
-		return rc;
174
-
175
-	/* Load image */
176
-	if ( ( rc = imgselect ( image ) ) != 0 ) {
177
-		printf ( "Could not select %s: %s\n",
178
-			 image->name, strerror ( rc ) );
179
-		return rc;
180
-	}
181
-
182
-	return 0;
222
+static int imgexec_exec ( int argc, char **argv) {
223
+	return imgsingle_exec ( argc, argv, &imgexec_desc );
183 224
 }
184 225
 
185
-/** "imgargs" options */
186
-struct imgargs_options {};
187
-
188
-/** "imgargs" option list */
189
-static struct option_descriptor imgargs_opts[] = {};
190
-
191
-/** "imgargs" command descriptor */
192
-static struct command_descriptor imgargs_cmd =
193
-	COMMAND_DESC ( struct imgargs_options, imgargs_opts, 1, MAX_ARGUMENTS,
194
-		       "<image> [<arguments>...]" );
226
+/** "imgargs" family command descriptor */
227
+struct imgsingle_descriptor imgargs_desc = {
228
+	.cmd = &imgsingle_cmd,
229
+	.acquire = imgacquire,
230
+	.preaction = image_clear_cmdline,
231
+};
195 232
 
196 233
 /**
197 234
  * The "imgargs" command body
@@ -201,105 +238,60 @@ static struct command_descriptor imgargs_cmd =
201 238
  * @ret rc		Return status code
202 239
  */
203 240
 static int imgargs_exec ( int argc, char **argv ) {
204
-	struct imgargs_options opts;
205
-	struct image *image;
206
-	char *cmdline = NULL;
207
-	int rc;
208
-
209
-	/* Parse options */
210
-	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
211
-		goto err_parse_options;
212
-
213
-	/* Parse image name */
214
-	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
215
-		goto err_parse_image;
216
-
217
-	/* Parse command line */
218
-	if ( argv[ optind + 1 ] != NULL ) {
219
-		cmdline = concat_args ( &argv[ optind + 1 ] );
220
-		if ( ! cmdline ) {
221
-			rc = -ENOMEM;
222
-			goto err_cmdline;
223
-		}
224
-	}
225
-
226
-	/* Set command line */
227
-	if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 )
228
-		goto err_set_cmdline;
229
-
230
-	/* Free command line */
231
-	free ( cmdline );
232
-
233
-	return 0;
234
-
235
- err_set_cmdline:
236
-	free ( cmdline );
237
- err_cmdline:
238
- err_parse_image:
239
- err_parse_options:
240
-	return rc;
241
+	return imgsingle_exec ( argc, argv, &imgargs_desc );
241 242
 }
242 243
 
243
-/** "imgexec" options */
244
-struct imgexec_options {};
244
+/** "img{multi}" options */
245
+struct imgmulti_options {};
245 246
 
246
-/** "imgexec" option list */
247
-static struct option_descriptor imgexec_opts[] = {};
247
+/** "img{multi}" option list */
248
+static struct option_descriptor imgmulti_opts[] = {};
248 249
 
249
-/** "imgexec" command descriptor */
250
-static struct command_descriptor imgexec_cmd =
251
-	COMMAND_DESC ( struct imgexec_options, imgexec_opts, 0, 1,
252
-		       "[<image>]" );
250
+/** "img{multi}" command descriptor */
251
+static struct command_descriptor imgmulti_cmd =
252
+	COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
253
+		       "[<image>...]" );
253 254
 
254 255
 /**
255
- * The "imgexec" command
256
+ * The "img{multi}" family of commands
256 257
  *
257 258
  * @v argc		Argument count
258 259
  * @v argv		Argument list
260
+ * @v payload		Function to execute on each image
259 261
  * @ret rc		Return status code
260 262
  */
261
-static int imgexec_exec ( int argc, char **argv ) {
262
-	struct imgexec_options opts;
263
+static int imgmulti_exec ( int argc, char **argv,
264
+			   void ( * payload ) ( struct image *image ) ) {
265
+	struct imgmulti_options opts;
263 266
 	struct image *image;
267
+	struct image *tmp;
268
+	int i;
264 269
 	int rc;
265 270
 
266 271
 	/* Parse options */
267
-	if ( ( rc = parse_options ( argc, argv, &imgexec_cmd, &opts ) ) != 0 )
272
+	if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
268 273
 		return rc;
269 274
 
270
-	/* Parse image name */
271
-	if ( optind < argc ) {
272
-		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
273
-			return rc;
274
-	} else {
275
-		image = imgautoselect();
276
-		if ( ! image ) {
277
-			rc = -ENOTTY;
278
-			printf ( "No image selected: %s\n", strerror ( rc ) );
279
-			return rc;
280
-		}
275
+	/* If no images are explicitly specified, process all images */
276
+	if ( optind == argc ) {
277
+		for_each_image_safe ( image, tmp )
278
+			payload ( image );
279
+		return 0;
281 280
 	}
282 281
 
283
-	/* Execute image */
284
-	if ( ( rc = imgexec ( image ) ) != 0 ) {
285
-		printf ( "Could not execute %s: %s\n",
286
-			 image->name, strerror ( rc ) );
287
-		return rc;
282
+	/* Otherwise, process specified images */
283
+	for ( i = optind ; i < argc ; i++ ) {
284
+		image = find_image ( argv[i] );
285
+		if ( ! image ) {
286
+			printf ( "\"%s\": no such image\n", argv[i] );
287
+			return -ENOENT;
288
+		}
289
+		payload ( image );
288 290
 	}
289 291
 
290 292
 	return 0;
291 293
 }
292 294
 
293
-/** "imgstat" options */
294
-struct imgstat_options {};
295
-
296
-/** "imgstat" option list */
297
-static struct option_descriptor imgstat_opts[] = {};
298
-
299
-/** "imgstat" command descriptor */
300
-static struct command_descriptor imgstat_cmd =
301
-	COMMAND_DESC ( struct imgstat_options, imgstat_opts, 0, 0, "" );
302
-
303 295
 /**
304 296
  * The "imgstat" command
305 297
  *
@@ -308,33 +300,9 @@ static struct command_descriptor imgstat_cmd =
308 300
  * @ret rc		Return status code
309 301
  */
310 302
 static int imgstat_exec ( int argc, char **argv ) {
311
-	struct imgstat_options opts;
312
-	struct image *image;
313
-	int rc;
314
-
315
-	/* Parse options */
316
-	if ( ( rc = parse_options ( argc, argv, &imgstat_cmd, &opts ) ) != 0 )
317
-		return rc;
318
-
319
-	/* Show status of all images */
320
-	for_each_image ( image ) {
321
-		imgstat ( image );
322
-	}
323
-
324
-	return 0;
303
+	return imgmulti_exec ( argc, argv, imgstat );
325 304
 }
326 305
 
327
-/** "imgfree" options */
328
-struct imgfree_options {};
329
-
330
-/** "imgfree" option list */
331
-static struct option_descriptor imgfree_opts[] = {};
332
-
333
-/** "imgfree" command descriptor */
334
-static struct command_descriptor imgfree_cmd =
335
-	COMMAND_DESC ( struct imgfree_options, imgfree_opts, 0, 1,
336
-		       "[<image>]" );
337
-
338 306
 /**
339 307
  * The "imgfree" command
340 308
  *
@@ -343,28 +311,7 @@ static struct command_descriptor imgfree_cmd =
343 311
  * @ret rc		Return status code
344 312
  */
345 313
 static int imgfree_exec ( int argc, char **argv ) {
346
-	struct imgfree_options opts;
347
-	struct image *image;
348
-	struct image *tmp;
349
-	int rc;
350
-
351
-	/* Parse options */
352
-	if ( ( rc = parse_options ( argc, argv, &imgfree_cmd, &opts ) ) != 0 )
353
-		return rc;
354
-
355
-	if ( optind < argc ) {
356
-		/* Free specified image */
357
-		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
358
-			return rc;
359
-		imgfree ( image );
360
-	} else {
361
-		/* Free all images */
362
-		list_for_each_entry_safe ( image, tmp, &images, list ) {
363
-			imgfree ( image );
364
-		}
365
-	}
366
-
367
-	return 0;
314
+	return imgmulti_exec ( argc, argv, unregister_image );
368 315
 }
369 316
 
370 317
 /** Image management commands */
@@ -383,19 +330,19 @@ struct command image_commands[] __command = {
383 330
 	},
384 331
 	{
385 332
 		.name = "kernel",
386
-		.exec = kernel_exec,
333
+		.exec = imgselect_exec, /* synonym for "imgselect" */
387 334
 	},
388 335
 	{
389 336
 		.name = "chain",
390
-		.exec = chain_exec,
337
+		.exec = imgexec_exec, /* synonym for "imgexec" */
391 338
 	},
392 339
 	{
393 340
 		.name = "imgselect",
394 341
 		.exec = imgselect_exec,
395 342
 	},
396 343
 	{
397
-		.name = "imgload", /* synonym for "imgselect" */
398
-		.exec = imgselect_exec,
344
+		.name = "imgload",
345
+		.exec = imgselect_exec, /* synonym for "imgselect" */
399 346
 	},
400 347
 	{
401 348
 		.name = "imgargs",

+ 10
- 9
src/include/ipxe/image.h Bestand weergeven

@@ -29,7 +29,7 @@ struct image {
29 29
 	/** URI of image */
30 30
 	struct uri *uri;
31 31
 	/** Name */
32
-	char name[16];
32
+	char *name;
33 33
 	/** Flags */
34 34
 	unsigned int flags;
35 35
 
@@ -122,6 +122,10 @@ extern struct image *current_image;
122 122
 #define for_each_image( image ) \
123 123
 	list_for_each_entry ( (image), &images, list )
124 124
 
125
+/** Iterate over all registered images, safe against deletion */
126
+#define for_each_image_safe( image, tmp ) \
127
+	list_for_each_entry_safe ( (image), (tmp), &images, list )
128
+
125 129
 /**
126 130
  * Test for existence of images
127 131
  *
@@ -140,8 +144,8 @@ static inline struct image * first_image ( void ) {
140 144
 	return list_first_entry ( &images, struct image, list );
141 145
 }
142 146
 
143
-extern struct image * alloc_image ( void );
144
-extern void image_set_uri ( struct image *image, struct uri *uri );
147
+extern struct image * alloc_image ( struct uri *uri );
148
+extern int image_set_name ( struct image *image, const char *name );
145 149
 extern int image_set_cmdline ( struct image *image, const char *cmdline );
146 150
 extern int register_image ( struct image *image );
147 151
 extern void unregister_image ( struct image *image );
@@ -174,15 +178,12 @@ static inline void image_put ( struct image *image ) {
174 178
 }
175 179
 
176 180
 /**
177
- * Set image name
181
+ * Clear image command line
178 182
  *
179 183
  * @v image		Image
180
- * @v name		New image name
181
- * @ret rc		Return status code
182 184
  */
183
-static inline int image_set_name ( struct image *image, const char *name ) {
184
-	strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
185
-	return 0;
185
+static inline void image_clear_cmdline ( struct image *image ) {
186
+	image_set_cmdline ( image, NULL );
186 187
 }
187 188
 
188 189
 /**

+ 0
- 2
src/include/ipxe/parseopt.h Bestand weergeven

@@ -13,7 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
13 13
 #include <stddef.h>
14 14
 
15 15
 struct net_device;
16
-struct image;
17 16
 
18 17
 /** A command-line option descriptor */
19 18
 struct option_descriptor {
@@ -117,7 +116,6 @@ struct command_descriptor {
117 116
 extern int parse_string ( const char *text, const char **value );
118 117
 extern int parse_integer ( const char *text, unsigned int *value );
119 118
 extern int parse_netdev ( const char *text, struct net_device **netdev );
120
-extern int parse_image ( const char *text, struct image **image );
121 119
 extern int parse_flag ( const char *text __unused, int *flag );
122 120
 extern void print_usage ( struct command_descriptor *cmd, char **argv );
123 121
 extern int reparse_options ( int argc, char **argv,

+ 3
- 35
src/include/usr/imgmgmt.h Bestand weergeven

@@ -11,41 +11,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 #include <ipxe/image.h>
13 13
 
14
-extern int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
15
-			 int ( * action ) ( struct image *image ) );
16
-extern int imgdownload_string ( const char *uri_string, const char *name,
17
-				const char *cmdline,
18
-				int ( * action ) ( struct image *image ) );
14
+extern int imgdownload ( struct uri *uri, struct image **image );
15
+extern int imgdownload_string ( const char *uri_string, struct image **image );
16
+extern int imgacquire ( const char *name, struct image **image );
19 17
 extern void imgstat ( struct image *image );
20
-extern void imgfree ( struct image *image );
21
-
22
-/**
23
- * Select an image for execution
24
- *
25
- * @v image		Image
26
- * @ret rc		Return status code
27
- */
28
-static inline int imgselect ( struct image *image ) {
29
-	return image_select ( image );
30
-}
31
-
32
-/**
33
- * Find the previously-selected image
34
- *
35
- * @ret image		Image, or NULL
36
- */
37
-static inline struct image * imgautoselect ( void ) {
38
-	return image_find_selected();
39
-}
40
-
41
-/**
42
- * Execute an image
43
- *
44
- * @v image		Image
45
- * @ret rc		Return status code
46
- */
47
-static inline int imgexec ( struct image *image ) {
48
-	return image_exec ( image );
49
-}
50 18
 
51 19
 #endif /* _USR_IMGMGMT_H */

+ 1
- 5
src/tests/test.c Bestand weergeven

@@ -149,12 +149,8 @@ static struct image_type test_image_type = {
149 149
 	.exec = test_image_exec,
150 150
 };
151 151
 
152
-static void test_image_free ( struct refcnt *refcnt __unused ) {
153
-	/* Do nothing */
154
-}
155
-
156 152
 static struct image test_image = {
157
-	.refcnt = REF_INIT ( test_image_free ),
153
+	.refcnt = REF_INIT ( ref_no_free ),
158 154
 	.name = "<TESTS>",
159 155
 	.type = &test_image_type,
160 156
 };

+ 6
- 3
src/usr/autoboot.c Bestand weergeven

@@ -131,6 +131,7 @@ struct setting skip_san_boot_setting __setting ( SETTING_SANBOOT_EXTRA ) = {
131 131
  */
132 132
 int uriboot ( struct uri *filename, struct uri *root_path, int drive,
133 133
 	      unsigned int flags ) {
134
+	struct image *image;
134 135
 	int rc;
135 136
 
136 137
 	/* Hook SAN device, if applicable */
@@ -157,9 +158,10 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
157 158
 
158 159
 	/* Attempt filename boot if applicable */
159 160
 	if ( filename ) {
160
-		if ( ( rc = imgdownload ( filename, NULL, NULL,
161
-					  image_exec ) ) != 0 ) {
162
-			printf ( "\nCould not chain image: %s\n",
161
+		if ( ( rc = imgdownload ( filename, &image ) ) != 0 )
162
+			goto err_download;
163
+		if ( ( rc = image_exec ( image ) ) != 0 ) {
164
+			printf ( "Could not boot image: %s\n",
163 165
 				 strerror ( rc ) );
164 166
 			/* Fall through to (possibly) attempt a SAN boot
165 167
 			 * as a fallback.  If no SAN boot is attempted,
@@ -190,6 +192,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
190 192
 		}
191 193
 	}
192 194
 
195
+ err_download:
193 196
  err_san_describe:
194 197
 	/* Unhook SAN device, if applicable */
195 198
 	if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_UNHOOK ) ) {

+ 36
- 43
src/usr/imgmgmt.c Bestand weergeven

@@ -36,39 +36,25 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 36
  */
37 37
 
38 38
 /**
39
- * Download an image
39
+ * Download a new image
40 40
  *
41 41
  * @v uri		URI
42
- * @v name		Image name, or NULL to use default
43
- * @v cmdline		Command line, or NULL for no command line
44
- * @v action		Action to take upon a successful download, or NULL
42
+ * @v image		Image to fill in
45 43
  * @ret rc		Return status code
46 44
  */
47
-int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
48
-		  int ( * action ) ( struct image *image ) ) {
49
-	struct image *image;
45
+int imgdownload ( struct uri *uri, struct image **image ) {
50 46
 	size_t len = ( unparse_uri ( NULL, 0, uri, URI_ALL ) + 1 );
51 47
 	char uri_string_redacted[len];
52 48
 	const char *password;
53 49
 	int rc;
54 50
 
55 51
 	/* Allocate image */
56
-	image = alloc_image();
57
-	if ( ! image ) {
52
+	*image = alloc_image ( uri );
53
+	if ( ! *image ) {
58 54
 		rc = -ENOMEM;
59 55
 		goto err_alloc_image;
60 56
 	}
61 57
 
62
-	/* Set image name */
63
-	if ( name )
64
-		image_set_name ( image, name );
65
-
66
-	/* Set image URI */
67
-	image_set_uri ( image, uri );
68
-
69
-	/* Set image command line */
70
-	image_set_cmdline ( image, cmdline );
71
-
72 58
 	/* Redact password portion of URI, if necessary */
73 59
 	password = uri->password;
74 60
 	if ( password )
@@ -78,8 +64,9 @@ int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
78 64
 	uri->password = password;
79 65
 
80 66
 	/* Create downloader */
81
-	if ( ( rc = create_downloader ( &monojob, image, LOCATION_URI,
67
+	if ( ( rc = create_downloader ( &monojob, *image, LOCATION_URI,
82 68
 					uri ) ) != 0 ) {
69
+		printf ( "Could not start download: %s\n", strerror ( rc ) );
83 70
 		goto err_create_downloader;
84 71
 	}
85 72
 
@@ -88,49 +75,64 @@ int imgdownload ( struct uri *uri, const char *name, const char *cmdline,
88 75
 		goto err_monojob_wait;
89 76
 
90 77
 	/* Register image */
91
-	if ( ( rc = register_image ( image ) ) != 0 )
78
+	if ( ( rc = register_image ( *image ) ) != 0 ) {
79
+		printf ( "Could not register image: %s\n", strerror ( rc ) );
92 80
 		goto err_register_image;
81
+	}
93 82
 
94 83
 	/* Drop local reference to image.  Image is guaranteed to
95 84
 	 * remain in scope since it is registered.
96 85
 	 */
97
-	image_put ( image );
86
+	image_put ( *image );
98 87
 
99
-	/* Carry out specified post-download action, if applicable */
100
-	return ( action ? action ( image ) : 0 );
88
+	return 0;
101 89
 
102 90
  err_register_image:
103 91
  err_monojob_wait:
104 92
  err_create_downloader:
105
-	image_put ( image );
93
+	image_put ( *image );
106 94
  err_alloc_image:
107 95
 	return rc;
108 96
 }
109 97
 
110 98
 /**
111
- * Download an image
99
+ * Download a new image
112 100
  *
113
- * @v uri_string	URI as a string (e.g. "http://www.nowhere.com/vmlinuz")
114
- * @v name		Image name, or NULL to use default
115
- * @v cmdline		Command line, or NULL for no command line
116
- * @v action		Action to take upon a successful download
101
+ * @v uri_string	URI string
102
+ * @v image		Image to fill in
117 103
  * @ret rc		Return status code
118 104
  */
119
-int imgdownload_string ( const char *uri_string, const char *name,
120
-			 const char *cmdline,
121
-			 int ( * action ) ( struct image *image ) ) {
105
+int imgdownload_string ( const char *uri_string, struct image **image ) {
122 106
 	struct uri *uri;
123 107
 	int rc;
124 108
 
125 109
 	if ( ! ( uri = parse_uri ( uri_string ) ) )
126 110
 		return -ENOMEM;
127 111
 
128
-	rc = imgdownload ( uri, name, cmdline, action );
112
+	rc = imgdownload ( uri, image );
129 113
 
130 114
 	uri_put ( uri );
131 115
 	return rc;
132 116
 }
133 117
 
118
+/**
119
+ * Acquire an image
120
+ *
121
+ * @v name_uri		Name or URI string
122
+ * @v image		Image to fill in
123
+ * @ret rc		Return status code
124
+ */
125
+int imgacquire ( const char *name_uri, struct image **image ) {
126
+
127
+	/* If we already have an image with the specified name, use it */
128
+	*image = find_image ( name_uri );
129
+	if ( *image )
130
+		return 0;
131
+
132
+	/* Otherwise, download a new image */
133
+	return imgdownload_string ( name_uri, image );
134
+}
135
+
134 136
 /**
135 137
  * Display status of an image
136 138
  *
@@ -148,12 +150,3 @@ void imgstat ( struct image *image ) {
148 150
 		printf ( " \"%s\"", image->cmdline );
149 151
 	printf ( "\n" );
150 152
 }
151
-
152
-/**
153
- * Free an image
154
- *
155
- * @v image		Executable/loadable image
156
- */
157
-void imgfree ( struct image *image ) {
158
-	unregister_image ( image );
159
-}

Laden…
Annuleren
Opslaan