Procházet zdrojové kódy

Allow images to hold references to the originating URI.

Some shuffling around of the image management code; this needs tidying up.
tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
d4947c05b2

+ 1
- 1
src/arch/i386/image/bzimage.c Zobrazit soubor

@@ -190,7 +190,7 @@ static size_t bzimage_load_initrd ( struct image *image,
190 190
 		return 0;
191 191
 
192 192
 	/* Create cpio header before non-prebuilt images */
193
-	if ( filename[0] ) {
193
+	if ( filename && filename[0] ) {
194 194
 		size_t name_len = ( strlen ( filename ) + 1 );
195 195
 
196 196
 		DBGC ( image, "bzImage %p inserting initrd %p as %s\n",

+ 7
- 2
src/arch/i386/image/multiboot.c Zobrazit soubor

@@ -135,6 +135,7 @@ multiboot_build_module_list ( struct image *image,
135 135
 	unsigned int insert;
136 136
 	physaddr_t start;
137 137
 	physaddr_t end;
138
+	char *cmdline;
138 139
 	unsigned int i;
139 140
 
140 141
 	/* Add each image as a multiboot module */
@@ -169,7 +170,9 @@ multiboot_build_module_list ( struct image *image,
169 170
 				  ( ( count - insert ) * sizeof ( *module ) ));
170 171
 			module->mod_start = start;
171 172
 			module->mod_end = end;
172
-			module->string = virt_to_phys ( module_image->cmdline);
173
+			cmdline = ( module_image->cmdline ?
174
+				    module_image->cmdline : "" );
175
+			module->string = virt_to_phys ( cmdline );
173 176
 			module->reserved = 0;
174 177
 			
175 178
 			/* We promise to page-align modules */
@@ -222,6 +225,7 @@ static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] );
222 225
  */
223 226
 static int multiboot_exec ( struct image *image ) {
224 227
 	physaddr_t entry = image->priv.phys;
228
+	char *cmdline;
225 229
 
226 230
 	/* Populate multiboot information structure */
227 231
 	memset ( &mbinfo, 0, sizeof ( mbinfo ) );
@@ -229,7 +233,8 @@ static int multiboot_exec ( struct image *image ) {
229 233
 			 MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
230 234
 	multiboot_build_memmap ( image, &mbinfo, mbmemmap,
231 235
 				 ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
232
-	mbinfo.cmdline = virt_to_phys ( image->cmdline );
236
+	cmdline = ( image->cmdline ? image->cmdline : "" );
237
+	mbinfo.cmdline = virt_to_phys ( cmdline );
233 238
 	mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
234 239
 				( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
235 240
 	mbinfo.mods_addr = virt_to_phys ( mbmodules );

+ 78
- 0
src/core/image.c Zobrazit soubor

@@ -22,8 +22,10 @@
22 22
 #include <stdio.h>
23 23
 #include <errno.h>
24 24
 #include <assert.h>
25
+#include <libgen.h>
25 26
 #include <gpxe/list.h>
26 27
 #include <gpxe/umalloc.h>
28
+#include <gpxe/uri.h>
27 29
 #include <gpxe/image.h>
28 30
 
29 31
 /** @file
@@ -49,6 +51,7 @@ static struct image_type image_types_end[0]
49 51
 static void free_image ( struct refcnt *refcnt ) {
50 52
 	struct image *image = container_of ( refcnt, struct image, refcnt );
51 53
 
54
+	uri_put ( image->uri );
52 55
 	ufree ( image->data );
53 56
 	free ( image );
54 57
 	DBGC ( image, "IMAGE %p freed\n", image );
@@ -69,6 +72,45 @@ struct image * alloc_image ( void ) {
69 72
 	return image;
70 73
 }
71 74
 
75
+/**
76
+ * Set image URI
77
+ *
78
+ * @v image		Image
79
+ * @v URI		New image URI
80
+ * @ret rc		Return status code
81
+ *
82
+ * If no name is set, the name will be updated to the base name of the
83
+ * URI path (if any).
84
+ */
85
+int image_set_uri ( struct image *image, struct uri *uri ) {
86
+	const char *path = uri->path;
87
+
88
+	/* Replace URI reference */
89
+	uri_put ( image->uri );
90
+	image->uri = uri_get ( uri );
91
+
92
+	/* Set name if none already specified */
93
+	if ( path && ( ! image->name[0] ) )
94
+		image_set_name ( image, basename ( ( char * ) path ) );
95
+
96
+	return 0;
97
+}
98
+
99
+/**
100
+ * Set image command line
101
+ *
102
+ * @v image		Image
103
+ * @v cmdline		New image command line
104
+ * @ret rc		Return status code
105
+ */
106
+int image_set_cmdline ( struct image *image, const char *cmdline ) {
107
+	free ( image->cmdline );
108
+	image->cmdline = strdup ( cmdline );
109
+	if ( ! image->cmdline )
110
+		return -ENOMEM;
111
+	return 0;
112
+}
113
+
72 114
 /**
73 115
  * Register executable/loadable image
74 116
  *
@@ -220,3 +262,39 @@ int image_exec ( struct image *image ) {
220 262
 	/* Well, some formats might return... */
221 263
 	return 0;
222 264
 }
265
+
266
+/**
267
+ * Register and autoload an image
268
+ *
269
+ * @v image		Image
270
+ * @ret rc		Return status code
271
+ */
272
+int register_and_autoload_image ( struct image *image ) {
273
+	int rc;
274
+
275
+	if ( ( rc = register_image ( image ) ) != 0 )
276
+		return rc;
277
+
278
+	if ( ( rc = image_autoload ( image ) ) != 0 )
279
+		return rc;
280
+
281
+	return 0;
282
+}
283
+
284
+/**
285
+ * Register and autoexec an image
286
+ *
287
+ * @v image		Image
288
+ * @ret rc		Return status code
289
+ */
290
+int register_and_autoexec_image ( struct image *image ) {
291
+	int rc;
292
+
293
+	if ( ( rc = register_and_autoload_image ( image ) ) != 0 )
294
+		return rc;
295
+
296
+	if ( ( rc = image_exec ( image ) ) != 0 )
297
+		return rc;
298
+
299
+	return 0;
300
+}

+ 59
- 24
src/hci/commands/image_cmd.c Zobrazit soubor

@@ -33,10 +33,11 @@
33 33
  *
34 34
  */
35 35
 
36
-/**
37
- * Print image description
38
- *
39
- */
36
+enum image_action {
37
+	IMG_FETCH = 0,
38
+	IMG_LOAD,
39
+	IMG_EXEC,
40
+};
40 41
 
41 42
 /**
42 43
  * Fill in image command line
@@ -44,17 +45,20 @@
44 45
  * @v image		Image
45 46
  * @v nargs		Argument count
46 47
  * @v args		Argument list
48
+ * @ret rc		Return status code
47 49
  */
48
-static void imgfill_cmdline ( struct image *image, unsigned int nargs, 
49
-                              char **args ) {
50
+static int imgfill_cmdline ( struct image *image, unsigned int nargs, 
51
+			     char **args ) {
52
+	char buf[256];
50 53
 	size_t used = 0;
51 54
 
52
-	image->cmdline[0] = '\0';
53
-	while ( ( used < sizeof ( image->cmdline ) ) && nargs-- ) {
54
-		used += snprintf ( &image->cmdline[used],
55
-				   ( sizeof ( image->cmdline ) - used ),
56
-				   "%s%s", ( used ? " " : "" ), *(args++) );
55
+	memset ( buf, 0, sizeof ( buf ) );
56
+	while ( ( used < sizeof ( buf ) ) && nargs-- ) {
57
+		used += snprintf ( &buf[used], ( sizeof ( buf ) - used ),
58
+				   " %s", *(args++) );
57 59
 	}
60
+
61
+	return image_set_cmdline ( image, &buf[1] );
58 62
 }
59 63
 
60 64
 /**
@@ -62,12 +66,18 @@ static void imgfill_cmdline ( struct image *image, unsigned int nargs,
62 66
  *
63 67
  * @v argv		Argument list
64 68
  */
65
-static void imgfetch_core_syntax ( char **argv, int load ) {
69
+static void imgfetch_core_syntax ( char **argv, enum image_action action ) {
70
+	static const char *actions[] = {
71
+		[IMG_FETCH]	= "Fetch",
72
+		[IMG_LOAD]	= "Fetch and load",
73
+		[IMG_EXEC]	= "Fetch and execute",
74
+	};
75
+
66 76
 	printf ( "Usage:\n"
67 77
 		 "  %s [-n|--name <name>] filename [arguments...]\n"
68 78
 		 "\n"
69 79
 		 "%s executable/loadable image\n",
70
-		 argv[0], ( load ? "Fetch and load" : "Fetch" ) );
80
+		 argv[0], actions[action] );
71 81
 }
72 82
 
73 83
 /**
@@ -79,7 +89,8 @@ static void imgfetch_core_syntax ( char **argv, int load ) {
79 89
  * @v argv		Argument list
80 90
  * @ret rc		Return status code
81 91
  */
82
-static int imgfetch_core_exec ( struct image_type *image_type, int load,
92
+static int imgfetch_core_exec ( struct image_type *image_type,
93
+				enum image_action action,
83 94
 				int argc, char **argv ) {
84 95
 	static struct option longopts[] = {
85 96
 		{ "help", 0, NULL, 'h' },
@@ -89,6 +100,7 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
89 100
 	struct image *image;
90 101
 	const char *name = NULL;
91 102
 	char *filename;
103
+	int ( * image_register ) ( struct image *image );
92 104
 	int c;
93 105
 	int rc;
94 106
 
@@ -104,14 +116,14 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
104 116
 			/* Display help text */
105 117
 		default:
106 118
 			/* Unrecognised/invalid option */
107
-			imgfetch_core_syntax ( argv, load );
119
+			imgfetch_core_syntax ( argv, action );
108 120
 			return -EINVAL;
109 121
 		}
110 122
 	}
111 123
 
112 124
 	/* Need at least a filename remaining after the options */
113 125
 	if ( optind == argc ) {
114
-		imgfetch_core_syntax ( argv, load );
126
+		imgfetch_core_syntax ( argv, action );
115 127
 		return -EINVAL;
116 128
 	}
117 129
 	filename = argv[optind++];
@@ -126,17 +138,35 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
126 138
 	}
127 139
 
128 140
 	/* Fill in image name */
129
-	if ( name )
130
-		strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
141
+	if ( name ) {
142
+		if ( ( rc = image_set_name ( image, name ) ) != 0 )
143
+			return rc;
144
+	}
131 145
 
132 146
 	/* Set image type (if specified) */
133 147
 	image->type = image_type;
134 148
 
135 149
 	/* Fill in command line */
136
-	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
150
+	if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
151
+				      &argv[optind] ) ) != 0 )
152
+		return rc;
137 153
 
138 154
 	/* Fetch the image */
139
-	if ( ( rc = imgfetch ( image, filename, load ) ) != 0 ) {
155
+	switch ( action ) {
156
+	case IMG_FETCH:
157
+		image_register = register_image;
158
+		break;
159
+	case IMG_LOAD:
160
+		image_register = register_and_autoload_image;
161
+		break;
162
+	case IMG_EXEC:
163
+		image_register = register_and_autoexec_image;
164
+		break;
165
+	default:
166
+		assert ( 0 );
167
+		return -EINVAL;
168
+	}
169
+	if ( ( rc = imgfetch ( image, filename, image_register ) ) != 0 ) {
140 170
 		printf ( "Could not fetch %s: %s\n", name, strerror ( rc ) );
141 171
 		image_put ( image );
142 172
 		return rc;
@@ -156,7 +186,8 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
156 186
 static int imgfetch_exec ( int argc, char **argv ) {
157 187
 	int rc;
158 188
 
159
-	if ( ( rc = imgfetch_core_exec ( NULL, 0, argc, argv ) ) != 0 )
189
+	if ( ( rc = imgfetch_core_exec ( NULL, IMG_FETCH,
190
+					 argc, argv ) ) != 0 )
160 191
 		return rc;
161 192
 
162 193
 	return 0;
@@ -172,7 +203,7 @@ static int imgfetch_exec ( int argc, char **argv ) {
172 203
 static int kernel_exec ( int argc, char **argv ) {
173 204
 	int rc;
174 205
 
175
-	if ( ( rc = imgfetch_core_exec ( NULL, 1, argc, argv ) ) != 0 )
206
+	if ( ( rc = imgfetch_core_exec ( NULL, IMG_LOAD, argc, argv ) ) != 0 )
176 207
 		return rc;
177 208
 
178 209
 	return 0;
@@ -188,7 +219,7 @@ static int kernel_exec ( int argc, char **argv ) {
188 219
 static int initrd_exec ( int argc, char **argv ) {
189 220
 	int rc;
190 221
 
191
-	if ( ( rc = imgfetch_core_exec ( &initrd_image_type, 0,
222
+	if ( ( rc = imgfetch_core_exec ( &initrd_image_type, IMG_FETCH,
192 223
 					 argc, argv ) ) != 0 )
193 224
 		return rc;
194 225
 
@@ -286,6 +317,7 @@ static int imgargs_exec ( int argc, char **argv ) {
286 317
 	struct image *image;
287 318
 	const char *name;
288 319
 	int c;
320
+	int rc;
289 321
 
290 322
 	/* Parse options */
291 323
 	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
@@ -312,7 +344,10 @@ static int imgargs_exec ( int argc, char **argv ) {
312 344
 		printf ( "No such image: %s\n", name );
313 345
 		return 1;
314 346
 	}
315
-	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
347
+	if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
348
+				      &argv[optind] ) ) != 0 )
349
+		return rc;
350
+
316 351
 
317 352
 	return 0;
318 353
 }

+ 23
- 6
src/include/gpxe/image.h Zobrazit soubor

@@ -13,25 +13,26 @@
13 13
 #include <gpxe/uaccess.h>
14 14
 #include <gpxe/refcnt.h>
15 15
 
16
+struct uri;
16 17
 struct image_type;
17 18
 
18
-/** Maximum length of a command line */
19
-#define CMDLINE_MAX 128
20
-
21 19
 /** An executable or loadable image */
22 20
 struct image {
23 21
 	/** Reference count */
24 22
 	struct refcnt refcnt;
25 23
 
26
-	/** Name */
27
-	char name[16];
28 24
 	/** List of registered images */
29 25
 	struct list_head list;
26
+
27
+	/** URI of image */
28
+	struct uri *uri;
29
+	/** Name */
30
+	char name[16];
30 31
 	/** Flags */
31 32
 	unsigned int flags;
32 33
 
33 34
 	/** Command line to pass to image */
34
-	char cmdline[CMDLINE_MAX];
35
+	char *cmdline;
35 36
 	/** Raw file image */
36 37
 	userptr_t data;
37 38
 	/** Length of raw file image */
@@ -114,6 +115,8 @@ extern struct list_head images;
114 115
 	list_for_each_entry ( (image), &images, list )
115 116
 
116 117
 extern struct image * alloc_image ( void );
118
+extern int image_set_uri ( struct image *image, struct uri *uri );
119
+extern int image_set_cmdline ( struct image *image, const char *cmdline );
117 120
 extern int register_image ( struct image *image );
118 121
 extern void unregister_image ( struct image *image );
119 122
 extern void promote_image ( struct image *image );
@@ -121,6 +124,8 @@ struct image * find_image ( const char *name );
121 124
 extern int image_load ( struct image *image );
122 125
 extern int image_autoload ( struct image *image );
123 126
 extern int image_exec ( struct image *image );
127
+extern int register_and_autoload_image ( struct image *image );
128
+extern int register_and_autoexec_image ( struct image *image );
124 129
 
125 130
 /**
126 131
  * Increment reference count on an image
@@ -142,4 +147,16 @@ static inline void image_put ( struct image *image ) {
142 147
 	ref_put ( &image->refcnt );
143 148
 }
144 149
 
150
+/**
151
+ * Set image name
152
+ *
153
+ * @v image		Image
154
+ * @v name		New image name
155
+ * @ret rc		Return status code
156
+ */
157
+static inline int image_set_name ( struct image *image, const char *name ) {
158
+	strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
159
+	return 0;
160
+}
161
+
145 162
 #endif /* _GPXE_IMAGE_H */

+ 2
- 2
src/include/gpxe/uri.h Zobrazit soubor

@@ -94,7 +94,7 @@ static inline int uri_has_absolute_path ( struct uri *uri ) {
94 94
  * @v uri			URI
95 95
  * @ret has_relative_path	URI has a relative path
96 96
  *
97
- * An relative path begins with something other than a '/'.  Note that
97
+ * A relative path begins with something other than a '/'.  Note that
98 98
  * this is a separate concept from a relative URI.  Note also that a
99 99
  * URI may not have a path at all.
100 100
  */
@@ -117,7 +117,7 @@ uri_get ( struct uri *uri ) {
117 117
 /**
118 118
  * Decrement URI reference count
119 119
  *
120
- * @v uri		URI
120
+ * @v uri		URI, or NULL
121 121
  */
122 122
 static inline __attribute__ (( always_inline )) void
123 123
 uri_put ( struct uri *uri ) {

+ 2
- 1
src/include/usr/imgmgmt.h Zobrazit soubor

@@ -9,7 +9,8 @@
9 9
 
10 10
 struct image;
11 11
 
12
-extern int imgfetch ( struct image *image, const char *filename, int load );
12
+extern int imgfetch ( struct image *image, const char *uri_string,
13
+		      int ( * image_register ) ( struct image *image ) );
13 14
 extern int imgload ( struct image *image );
14 15
 extern int imgexec ( struct image *image );
15 16
 extern struct image * imgautoselect ( void );

+ 3
- 13
src/usr/autoboot.c Zobrazit soubor

@@ -60,25 +60,15 @@ static int boot_filename ( const char *filename ) {
60 60
 		printf ( "Out of memory\n" );
61 61
 		return -ENOMEM;
62 62
 	}
63
-	if ( ( rc = imgfetch ( image, filename, 0 ) ) != 0 ) {
63
+	if ( ( rc = imgfetch ( image, filename,
64
+			       register_and_autoexec_image ) ) != 0 ) {
64 65
 		printf ( "Could not retrieve %s: %s\n",
65 66
 			 filename, strerror ( rc ) );
66 67
 		image_put ( image );
67 68
 		return rc;
68 69
 	}
69
-	if ( ( rc = imgload ( image ) ) != 0 ) {
70
-		printf ( "Could not load %s: %s\n", image->name,
71
-			 strerror ( rc ) );
72
-		image_put ( image );
73
-		return rc;
74
-	}
75
-	if ( ( rc = imgexec ( image ) ) != 0 ) {
76
-		printf ( "Could not execute %s: %s\n", image->name,
77
-			 strerror ( rc ) );
78
-		image_put ( image );
79
-		return rc;
80
-	}
81 70
 
71
+	image_put ( image );
82 72
 	return 0;
83 73
 }
84 74
 

+ 14
- 20
src/usr/imgmgmt.c Zobrazit soubor

@@ -24,6 +24,7 @@
24 24
 #include <gpxe/downloader.h>
25 25
 #include <gpxe/monojob.h>
26 26
 #include <gpxe/open.h>
27
+#include <gpxe/uri.h>
27 28
 #include <usr/imgmgmt.h>
28 29
 
29 30
 /** @file
@@ -32,36 +33,29 @@
32 33
  *
33 34
  */
34 35
 
35
-static int imgfetch_autoload ( struct image *image ) {
36
-	int rc;
37
-
38
-	if ( ( rc = register_image ( image ) ) != 0 )
39
-		return rc;
40
-
41
-	if ( ( rc = image_autoload ( image ) ) != 0 )
42
-		return rc;
43
-
44
-	return 0;
45
-}
46
-
47 36
 /**
48 37
  * Fetch an image
49 38
  *
50 39
  * @v uri_string	URI as a string (e.g. "http://www.nowhere.com/vmlinuz")
51 40
  * @v name		Name for image, or NULL
52
- * @ret new_image	Newly created image
41
+ * @v register_image	Image registration routine
53 42
  * @ret rc		Return status code
54 43
  */
55
-int imgfetch ( struct image *image, const char *uri_string, int load ) {
44
+int imgfetch ( struct image *image, const char *uri_string,
45
+	       int ( * image_register ) ( struct image *image ) ) {
46
+	struct uri *uri;
56 47
 	int rc;
57 48
 
58
-	if ( ( rc = create_downloader ( &monojob, image, 
59
-					( load ? imgfetch_autoload :
60
-					  register_image ),
61
-					LOCATION_URI_STRING,
62
-					uri_string ) ) == 0 )
49
+	if ( ! ( uri = parse_uri ( uri_string ) ) )
50
+		return -ENOMEM;
51
+
52
+	image_set_uri ( image, uri );
53
+
54
+	if ( ( rc = create_downloader ( &monojob, image, image_register,
55
+					LOCATION_URI, uri ) ) == 0 )
63 56
 		rc = monojob_wait();
64 57
 
58
+	uri_put ( uri );
65 59
 	return rc;
66 60
 }
67 61
 
@@ -118,7 +112,7 @@ void imgstat ( struct image *image ) {
118 112
 		printf ( " [%s]", image->type->name );
119 113
 	if ( image->flags & IMAGE_LOADED )
120 114
 		printf ( " [LOADED]" );
121
-	if ( image->cmdline[0] )
115
+	if ( image->cmdline )
122 116
 		printf ( " \"%s\"", image->cmdline );
123 117
 	printf ( "\n" );
124 118
 }

Načítá se…
Zrušit
Uložit