Browse Source

Cleaner separation between imgXXX() functions and image_cmd.c

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
f135a37f30
4 changed files with 389 additions and 60 deletions
  1. 309
    51
      src/hci/commands/image_cmd.c
  2. 5
    0
      src/include/usr/imgmgmt.h
  3. 0
    7
      src/usr/fetch.c
  4. 75
    2
      src/usr/imgmgmt.c

+ 309
- 51
src/hci/commands/image_cmd.c View File

18
 
18
 
19
 #include <stdint.h>
19
 #include <stdint.h>
20
 #include <stdlib.h>
20
 #include <stdlib.h>
21
+#include <libgen.h>
21
 #include <getopt.h>
22
 #include <getopt.h>
22
 #include <vsprintf.h>
23
 #include <vsprintf.h>
23
 #include <gpxe/image.h>
24
 #include <gpxe/image.h>
24
 #include <gpxe/command.h>
25
 #include <gpxe/command.h>
25
-#include <usr/fetch.h>
26
 #include <usr/imgmgmt.h>
26
 #include <usr/imgmgmt.h>
27
 
27
 
28
 /** @file
28
 /** @file
37
  */
37
  */
38
 
38
 
39
 /**
39
 /**
40
- * "fetch"/"module"/"kernel" command syntax message
40
+ * Fill in image command line
41
+ *
42
+ * @v image		Image
43
+ * @v nargs		Argument count
44
+ * @v args		Argument list
45
+ */
46
+void imgfill_cmdline ( struct image *image, unsigned int nargs, char **args ) {
47
+	size_t used = 0;
48
+
49
+	image->cmdline[0] = '\0';
50
+	while ( ( used < sizeof ( image->cmdline ) ) && nargs-- ) {
51
+		used += snprintf ( &image->cmdline[used],
52
+				   ( sizeof ( image->cmdline ) - used ),
53
+				   "%s%s", ( used ? " " : "" ), *(args++) );
54
+	}
55
+}
56
+
57
+/**
58
+ * "imgfetch"/"module"/"kernel" command syntax message
41
  *
59
  *
42
  * @v argv		Argument list
60
  * @v argv		Argument list
43
  */
61
  */
44
-static void fetch_syntax ( char **argv ) {
62
+static void imgfetch_core_syntax ( char **argv, int load ) {
45
 	printf ( "Usage:\n"
63
 	printf ( "Usage:\n"
46
 		 "  %s [-n|--name <name>] filename [arguments...]\n"
64
 		 "  %s [-n|--name <name>] filename [arguments...]\n"
47
 		 "\n"
65
 		 "\n"
48
-		 "Fetch executable/loadable image\n",
49
-		 argv[0] );
66
+		 "%s executable/loadable image\n",
67
+		 argv[0], ( load ? "Fetch and load" : "Fetch" ) );
50
 }
68
 }
51
 
69
 
52
 /**
70
 /**
53
- * The "fetch"/"module"/"kernel" command body
71
+ * The "imgfetch"/"module"/"kernel" command body
54
  *
72
  *
55
  * @v argc		Argument count
73
  * @v argc		Argument count
56
  * @v argv		Argument list
74
  * @v argv		Argument list
57
- * @v name		Default name for image, or NULL
75
+ * @v load		Load image after fetching
58
  * @ret rc		Exit code
76
  * @ret rc		Exit code
59
  */
77
  */
60
-static int fetch_exec_name ( int argc, char **argv, const char *name ) {
78
+static int imgfetch_core_exec ( int argc, char **argv, int load ) {
61
 	static struct option longopts[] = {
79
 	static struct option longopts[] = {
62
 		{ "help", 0, NULL, 'h' },
80
 		{ "help", 0, NULL, 'h' },
63
 		{ "name", required_argument, NULL, 'n' },
81
 		{ "name", required_argument, NULL, 'n' },
64
 		{ NULL, 0, NULL, 0 },
82
 		{ NULL, 0, NULL, 0 },
65
 	};
83
 	};
66
 	struct image *image;
84
 	struct image *image;
67
-	const char *filename;
68
-	char cmdline[ sizeof ( image->cmdline ) ];
69
-	size_t used = 0;
85
+	const char *name = NULL;
86
+	char *filename;
70
 	int c;
87
 	int c;
71
 	int rc;
88
 	int rc;
72
 
89
 
82
 			/* Display help text */
99
 			/* Display help text */
83
 		default:
100
 		default:
84
 			/* Unrecognised/invalid option */
101
 			/* Unrecognised/invalid option */
85
-			fetch_syntax ( argv );
102
+			imgfetch_core_syntax ( argv, load );
86
 			return 1;
103
 			return 1;
87
 		}
104
 		}
88
 	}
105
 	}
89
 
106
 
90
 	/* Need at least a filename remaining after the options */
107
 	/* Need at least a filename remaining after the options */
91
-	if ( optind >= argc ) {
92
-		fetch_syntax ( argv );
108
+	if ( optind == argc ) {
109
+		imgfetch_core_syntax ( argv, load );
93
 		return 1;
110
 		return 1;
94
 	}
111
 	}
95
 	filename = argv[optind++];
112
 	filename = argv[optind++];
113
+	if ( ! name )
114
+		name = basename ( filename );
96
 
115
 
97
-	/* Build command line */
98
-	while ( ( used < sizeof ( cmdline ) ) && ( optind < argc ) ) {
99
-		used += snprintf ( &cmdline[used], sizeof ( cmdline ) - used,
100
-				   " %s",  argv[optind++] );
116
+	/* Fetch the image */
117
+	if ( ( rc = imgfetch ( filename, name, &image ) ) != 0 ) {
118
+		printf ( "Could not fetch %s: %s\n", name, strerror ( rc ) );
119
+		return 1;
101
 	}
120
 	}
102
 
121
 
103
-	/* Allocate and fill struct image */
104
-	image = malloc ( sizeof ( *image ) );
105
-	if ( ! image ) {
106
-		printf ( "Out of memory\n" );
107
-		return 1;
122
+	/* Fill in command line */
123
+	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
124
+
125
+	/* Load image if required */
126
+	if ( load ) {
127
+		if ( ( rc = imgload ( image ) ) != 0 ) {
128
+			printf ( "Could not load %s: %s\n", name,
129
+				 strerror ( rc ) );
130
+			return 1;
131
+		}
108
 	}
132
 	}
109
-	memset ( image, 0, sizeof ( *image ) );
110
-	if ( name )
111
-		strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
112
-	if ( used )
113
-		memcpy ( image->cmdline, cmdline, sizeof ( image->cmdline ) );
114
-
115
-	/* Fetch the file */
116
-	if ( ( rc = fetch ( image, filename ) ) != 0 ) {
117
-		printf ( "Could not fetch %s: %s\n", filename,
118
-			 strerror ( rc ) );
119
-		free ( image );
133
+
134
+	return 0;
135
+}
136
+
137
+/**
138
+ * The "imgfetch"/"module" command
139
+ *
140
+ * @v argc		Argument count
141
+ * @v argv		Argument list
142
+ * @ret rc		Exit code
143
+ */
144
+static int imgfetch_exec ( int argc, char **argv ) {
145
+	return imgfetch_core_exec ( argc, argv, 0 );
146
+}
147
+
148
+/**
149
+ * The "kernel" command
150
+ *
151
+ * @v argc		Argument count
152
+ * @v argv		Argument list
153
+ * @ret rc		Exit code
154
+ */
155
+static int kernel_exec ( int argc, char **argv ) {
156
+	return imgfetch_core_exec ( argc, argv, 1  );
157
+}
158
+
159
+/**
160
+ * "imgload" command syntax message
161
+ *
162
+ * @v argv		Argument list
163
+ */
164
+static void imgload_syntax ( char **argv ) {
165
+	printf ( "Usage:\n"
166
+		 "  %s <image name>\n"
167
+		 "\n"
168
+		 "Load executable/loadable image\n",
169
+		 argv[0] );
170
+}
171
+
172
+/**
173
+ * The "imgload" command
174
+ *
175
+ * @v argc		Argument count
176
+ * @v argv		Argument list
177
+ * @ret rc		Exit code
178
+ */
179
+static int imgload_exec ( int argc, char **argv ) {
180
+	static struct option longopts[] = {
181
+		{ "help", 0, NULL, 'h' },
182
+		{ NULL, 0, NULL, 0 },
183
+	};
184
+	struct image *image;
185
+	const char *name;
186
+	int c;
187
+	int rc;
188
+
189
+	/* Parse options */
190
+	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
191
+		switch ( c ) {
192
+		case 'h':
193
+			/* Display help text */
194
+		default:
195
+			/* Unrecognised/invalid option */
196
+			imgload_syntax ( argv );
197
+			return 1;
198
+		}
199
+	}
200
+
201
+	/* Need exactly one image name remaining after the options */
202
+	if ( optind != ( argc - 1 ) ) {
203
+		imgload_syntax ( argv );
120
 		return 1;
204
 		return 1;
121
 	}
205
 	}
206
+	name = argv[optind];
122
 
207
 
123
-	/* Register the image */
124
-	if ( ( rc = register_image ( image ) ) != 0 ) {
125
-		printf ( "Could not register %s: %s\n", filename,
126
-			 strerror ( rc ) );
127
-		free ( image );
208
+	/* Load all specified images */
209
+	image = find_image ( name );
210
+	if ( ! image ) {
211
+		printf ( "No such image: %s\n", name );
212
+		return 1;
213
+	}
214
+	if ( ( rc = imgload ( image ) ) != 0 ) {
215
+		printf ( "Could not load %s: %s\n", name, strerror ( rc ) );
128
 		return 1;
216
 		return 1;
129
 	}
217
 	}
130
 
218
 
131
-	imgstat ( image );
132
 	return 0;
219
 	return 0;
133
 }
220
 }
134
 
221
 
135
 /**
222
 /**
136
- * The "fetch"/"module" command
223
+ * "imgargs" command syntax message
224
+ *
225
+ * @v argv		Argument list
226
+ */
227
+static void imgargs_syntax ( char **argv ) {
228
+	printf ( "Usage:\n"
229
+		 "  %s <image name> [<arguments>...]\n"
230
+		 "\n"
231
+		 "Set arguments for executable/loadable image\n",
232
+		 argv[0] );
233
+}
234
+
235
+/**
236
+ * The "imgargs" command body
137
  *
237
  *
138
  * @v argc		Argument count
238
  * @v argc		Argument count
139
  * @v argv		Argument list
239
  * @v argv		Argument list
140
  * @ret rc		Exit code
240
  * @ret rc		Exit code
141
  */
241
  */
142
-static int fetch_exec ( int argc, char **argv ) {
143
-	return fetch_exec_name ( argc, argv, NULL );
242
+static int imgargs_exec ( int argc, char **argv ) {
243
+	static struct option longopts[] = {
244
+		{ "help", 0, NULL, 'h' },
245
+		{ NULL, 0, NULL, 0 },
246
+	};
247
+	struct image *image;
248
+	const char *name;
249
+	int c;
250
+
251
+	/* Parse options */
252
+	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
253
+		switch ( c ) {
254
+		case 'h':
255
+			/* Display help text */
256
+		default:
257
+			/* Unrecognised/invalid option */
258
+			imgargs_syntax ( argv );
259
+			return 1;
260
+		}
261
+	}
262
+
263
+	/* Need at least an image name remaining after the options */
264
+	if ( optind == argc ) {
265
+		imgargs_syntax ( argv );
266
+		return 1;
267
+	}
268
+	name = argv[optind++];
269
+
270
+	/* Fill in command line */
271
+	image = find_image ( name );
272
+	if ( ! image ) {
273
+		printf ( "No such image: %s\n", name );
274
+		return 1;
275
+	}
276
+	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
277
+
278
+	return 0;
279
+}
280
+
281
+/**
282
+ * "imgexec" command syntax message
283
+ *
284
+ * @v argv		Argument list
285
+ */
286
+static void imgexec_syntax ( char **argv ) {
287
+	printf ( "Usage:\n"
288
+		 "  %s <image name>\n"
289
+		 "\n"
290
+		 "Execute executable/loadable image\n",
291
+		 argv[0] );
144
 }
292
 }
145
 
293
 
146
 /**
294
 /**
147
- * The "kernel" command
295
+ * The "imgexec" command
148
  *
296
  *
149
  * @v argc		Argument count
297
  * @v argc		Argument count
150
  * @v argv		Argument list
298
  * @v argv		Argument list
151
  * @ret rc		Exit code
299
  * @ret rc		Exit code
152
  */
300
  */
153
-static int kernel_exec ( int argc, char **argv ) {
154
-	return fetch_exec_name ( argc, argv, "kernel" );
301
+static int imgexec_exec ( int argc, char **argv ) {
302
+	static struct option longopts[] = {
303
+		{ "help", 0, NULL, 'h' },
304
+		{ NULL, 0, NULL, 0 },
305
+	};
306
+	struct image *image;
307
+	const char *name;
308
+	int c;
309
+	int rc;
310
+
311
+	/* Parse options */
312
+	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
313
+		switch ( c ) {
314
+		case 'h':
315
+			/* Display help text */
316
+		default:
317
+			/* Unrecognised/invalid option */
318
+			imgexec_syntax ( argv );
319
+			return 1;
320
+		}
321
+	}
322
+
323
+	/* Need exactly one image name */
324
+	if ( optind != ( argc - 1 ) ) {
325
+		imgexec_syntax ( argv );
326
+		return 1;
327
+	}
328
+	name = argv[optind];
329
+	
330
+	/* Execute specified image */
331
+	image = find_image ( name );
332
+	if ( ! image ) {
333
+		printf ( "No such image: %s\n", name );
334
+		return 1;
335
+	}
336
+	if ( ( rc = imgexec ( image ) ) != 0 ) {
337
+		printf ( "Could not execute %s: %s\n", name, strerror ( rc ) );
338
+		return 1;
339
+	}
340
+
341
+	return 0;
155
 }
342
 }
156
 
343
 
157
 /**
344
 /**
174
  * @v argv		Argument list
361
  * @v argv		Argument list
175
  * @ret rc		Exit code
362
  * @ret rc		Exit code
176
  */
363
  */
177
-static int imgstat_exec ( int argc __unused, char **argv __unused ) {
364
+static int imgstat_exec ( int argc, char **argv ) {
178
 	static struct option longopts[] = {
365
 	static struct option longopts[] = {
179
 		{ "help", 0, NULL, 'h' },
366
 		{ "help", 0, NULL, 'h' },
180
 		{ NULL, 0, NULL, 0 },
367
 		{ NULL, 0, NULL, 0 },
194
 		}
381
 		}
195
 	}
382
 	}
196
 
383
 
197
-	/* Need at least a filename remaining after the options */
384
+	/* No arguments */
198
 	if ( optind != argc ) {
385
 	if ( optind != argc ) {
199
 		imgstat_syntax ( argv );
386
 		imgstat_syntax ( argv );
200
 		return 1;
387
 		return 1;
207
 	return 0;
394
 	return 0;
208
 }
395
 }
209
 
396
 
397
+/**
398
+ * "imgstat" command syntax message
399
+ *
400
+ * @v argv		Argument list
401
+ */
402
+static void imgfree_syntax ( char **argv ) {
403
+	printf ( "Usage:\n"
404
+		 "  %s\n"
405
+		 "\n"
406
+		 "Free all executable/loadable images\n",
407
+		 argv[0] );
408
+}
409
+
410
+/**
411
+ * The "imgfree" command
412
+ *
413
+ * @v argc		Argument count
414
+ * @v argv		Argument list
415
+ * @ret rc		Exit code
416
+ */
417
+static int imgfree_exec ( int argc, char **argv ) {
418
+	static struct option longopts[] = {
419
+		{ "help", 0, NULL, 'h' },
420
+		{ NULL, 0, NULL, 0 },
421
+	};
422
+	struct image *image;
423
+	struct image *tmp;
424
+	int c;
425
+
426
+	/* Parse options */
427
+	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
428
+		switch ( c ) {
429
+		case 'h':
430
+			/* Display help text */
431
+		default:
432
+			/* Unrecognised/invalid option */
433
+			imgfree_syntax ( argv );
434
+			return 1;
435
+		}
436
+	}
437
+
438
+	/* No arguments */
439
+	if ( optind != argc ) {
440
+		imgfree_syntax ( argv );
441
+		return 1;
442
+	}
443
+
444
+	/* Free all images */
445
+	list_for_each_entry_safe ( image, tmp, &images, list ) {
446
+		imgfree ( image );
447
+	}
448
+	return 0;
449
+}
450
+
451
+
210
 /** Image management commands */
452
 /** Image management commands */
211
 struct command image_commands[] __command = {
453
 struct command image_commands[] __command = {
212
 	{
454
 	{
213
-		.name = "fetch",
214
-		.exec = fetch_exec,
455
+		.name = "imgfetch",
456
+		.exec = imgfetch_exec,
215
 	},
457
 	},
216
 	{
458
 	{
217
 		.name = "module",
459
 		.name = "module",
218
-		.exec = fetch_exec, /* synonym for "fetch" */
460
+		.exec = imgfetch_exec, /* synonym for "imgfetch" */
219
 	},
461
 	},
220
 	{
462
 	{
221
 		.name = "kernel",
463
 		.name = "kernel",
222
 		.exec = kernel_exec,
464
 		.exec = kernel_exec,
223
 	},
465
 	},
466
+	{
467
+		.name = "imgload",
468
+		.exec = imgload_exec,
469
+	},
470
+	{
471
+		.name = "imgargs",
472
+		.exec = imgargs_exec,
473
+	},
474
+	{
475
+		.name = "imgexec",
476
+		.exec = imgexec_exec,
477
+	},
224
 	{
478
 	{
225
 		.name = "imgstat",
479
 		.name = "imgstat",
226
 		.exec = imgstat_exec,
480
 		.exec = imgstat_exec,
227
 	},
481
 	},
482
+	{
483
+		.name = "imgfree",
484
+		.exec = imgfree_exec,
485
+	},
228
 };
486
 };

+ 5
- 0
src/include/usr/imgmgmt.h View File

7
  *
7
  *
8
  */
8
  */
9
 
9
 
10
+extern int imgfetch ( const char *filename, const char *name,
11
+		      struct image **new_image );
12
+extern int imgload ( struct image *image );
13
+extern int imgexec ( struct image *image );
10
 extern void imgstat ( struct image *image );
14
 extern void imgstat ( struct image *image );
15
+extern void imgfree ( struct image *image );
11
 
16
 
12
 #endif /* _USR_IMGMGMT_H */
17
 #endif /* _USR_IMGMGMT_H */

+ 0
- 7
src/usr/fetch.c View File

23
  *
23
  *
24
  */
24
  */
25
 
25
 
26
-#include <libgen.h>
27
 #include <vsprintf.h>
26
 #include <vsprintf.h>
28
 #include <gpxe/emalloc.h>
27
 #include <gpxe/emalloc.h>
29
 #include <gpxe/ebuffer.h>
28
 #include <gpxe/ebuffer.h>
45
 	struct buffer buffer;
44
 	struct buffer buffer;
46
 	int rc;
45
 	int rc;
47
 
46
 
48
-	/* Name the image, if it isn't explicitly named */
49
-	if ( ! image->name[0] ) {
50
-		strncpy ( image->name, basename ( filename ),
51
-			  ( sizeof ( image->name ) - 1 ) );
52
-	}
53
-
54
 	/* Allocate an expandable buffer to hold the file */
47
 	/* Allocate an expandable buffer to hold the file */
55
 	if ( ( rc = ebuffer_alloc ( &buffer, 0 ) ) != 0 )
48
 	if ( ( rc = ebuffer_alloc ( &buffer, 0 ) ) != 0 )
56
 		return rc;
49
 		return rc;

+ 75
- 2
src/usr/imgmgmt.c View File

17
  */
17
  */
18
 
18
 
19
 #include <stdint.h>
19
 #include <stdint.h>
20
+#include <stdlib.h>
21
+#include <errno.h>
20
 #include <vsprintf.h>
22
 #include <vsprintf.h>
21
 #include <gpxe/image.h>
23
 #include <gpxe/image.h>
24
+#include <usr/fetch.h>
22
 #include <usr/imgmgmt.h>
25
 #include <usr/imgmgmt.h>
23
 
26
 
24
 /** @file
27
 /** @file
27
  *
30
  *
28
  */
31
  */
29
 
32
 
33
+/**
34
+ * Fetch an image
35
+ *
36
+ * @v filename		Filename for image
37
+ * @v name		Name for image, or NULL
38
+ * @ret new_image	Newly created image
39
+ * @ret rc		Return status code
40
+ */
41
+int imgfetch ( const char *filename, const char *name,
42
+	       struct image **new_image ) {
43
+	struct image *image;
44
+	int rc;
45
+
46
+	/* Allocate new image */
47
+	image = malloc ( sizeof ( *image ) );
48
+	if ( ! image )
49
+		return -ENOMEM;
50
+	memset ( image, 0, sizeof ( *image ) );
51
+
52
+	/* Fill in image name */
53
+	if ( name )
54
+		strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
55
+
56
+	/* Fetch the file */
57
+	if ( ( rc = fetch ( image, filename ) ) != 0 )
58
+		goto err;
59
+
60
+	/* Register the image */
61
+	if ( ( rc = register_image ( image ) ) != 0 )
62
+		goto err;
63
+
64
+	*new_image = image;
65
+	return 0;
66
+
67
+ err:
68
+	free_image ( image );
69
+	free ( image );
70
+	return rc;
71
+}
72
+
73
+/**
74
+ * Load an image
75
+ *
76
+ * @v image		Image
77
+ * @ret rc		Return status code
78
+ */
79
+int imgload ( struct image *image ) {
80
+	return image_autoload ( image );
81
+}
82
+
83
+/**
84
+ * Execute an image
85
+ *
86
+ * @v image		Image
87
+ * @ret rc		Return status code
88
+ */
89
+int imgexec ( struct image *image ) {
90
+	return image_exec ( image );
91
+}
92
+
30
 /**
93
 /**
31
  * Display status of an image
94
  * Display status of an image
32
  *
95
  *
33
  * @v image		Executable/loadable image
96
  * @v image		Executable/loadable image
34
  */
97
  */
35
 void imgstat ( struct image *image ) {
98
 void imgstat ( struct image *image ) {
36
-	printf ( "%s: %zd bytes ", image->name, image->len );
99
+	printf ( "%s: %zd bytes", image->name, image->len );
37
 	if ( image->type )
100
 	if ( image->type )
38
 		printf ( " [%s]", image->type->name );
101
 		printf ( " [%s]", image->type->name );
39
 	if ( image->flags & IMAGE_LOADED )
102
 	if ( image->flags & IMAGE_LOADED )
40
 		printf ( " [LOADED]" );
103
 		printf ( " [LOADED]" );
41
 	if ( image->cmdline[0] )
104
 	if ( image->cmdline[0] )
42
-		printf ( "\"%s\"", image->cmdline );
105
+		printf ( " \"%s\"", image->cmdline );
43
 	printf ( "\n" );
106
 	printf ( "\n" );
44
 }
107
 }
45
 
108
 
109
+/**
110
+ * Free an image
111
+ *
112
+ * @v image		Executable/loadable image
113
+ */
114
+void imgfree ( struct image *image ) {
115
+	unregister_image ( image );
116
+	free_image ( image );
117
+	free ( image );
118
+}

Loading…
Cancel
Save