Browse Source

[image] Detect image type when image is first registered

The current usage pattern of image_probe() is a legacy from the time
before commit 34b6ecb ("[image] Simplify image management") when
loading an image to its executable location in memory was a separate
action from actually executing the image.

Call image_probe() as soon as an image is registered.  This allows
"imgstat" to display image type information for all images and allows
image-consuming code to assume that image->type is already set
correctly.

Ignore failures if image_probe() does not recognise the image, since
we do expect to handle unrecognised images (initrds, modules, etc).
Unrecognised images will be left with a NULL image->type, which
image-consuming code can easily check.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
abfe94a90a
3 changed files with 47 additions and 44 deletions
  1. 42
    41
      src/core/image.c
  2. 0
    1
      src/include/ipxe/image.h
  3. 5
    2
      src/tests/pixbuf_test.c

+ 42
- 41
src/core/image.c View File

157
 	return 0;
157
 	return 0;
158
 }
158
 }
159
 
159
 
160
+/**
161
+ * Determine image type
162
+ *
163
+ * @v image		Executable image
164
+ * @ret rc		Return status code
165
+ */
166
+static int image_probe ( struct image *image ) {
167
+	struct image_type *type;
168
+	int rc;
169
+
170
+	/* Try each type in turn */
171
+	for_each_table_entry ( type, IMAGE_TYPES ) {
172
+		if ( ( rc = type->probe ( image ) ) == 0 ) {
173
+			image->type = type;
174
+			DBGC ( image, "IMAGE %s is %s\n",
175
+			       image->name, type->name );
176
+			break;
177
+		}
178
+		DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
179
+		       type->name, strerror ( rc ) );
180
+	}
181
+
182
+	DBGC ( image, "IMAGE %s format not recognised\n", image->name );
183
+	return -ENOTSUP;
184
+}
185
+
160
 /**
186
 /**
161
  * Register executable image
187
  * Register executable image
162
  *
188
  *
189
 	       image->name, user_to_phys ( image->data, 0 ),
215
 	       image->name, user_to_phys ( image->data, 0 ),
190
 	       user_to_phys ( image->data, image->len ) );
216
 	       user_to_phys ( image->data, image->len ) );
191
 
217
 
218
+	/* Try to detect image type, if applicable.  Ignore failures,
219
+	 * since we expect to handle some unrecognised images
220
+	 * (e.g. kernel initrds, multiboot modules, random files
221
+	 * provided via our EFI virtual filesystem, etc).
222
+	 */
223
+	if ( ! image->type )
224
+		image_probe ( image );
225
+
192
 	return 0;
226
 	return 0;
193
 }
227
 }
194
 
228
 
226
 	return NULL;
260
 	return NULL;
227
 }
261
 }
228
 
262
 
229
-/**
230
- * Determine image type
231
- *
232
- * @v image		Executable image
233
- * @ret rc		Return status code
234
- */
235
-int image_probe ( struct image *image ) {
236
-	struct image_type *type;
237
-	int rc;
238
-
239
-	/* Succeed if we already have a type */
240
-	if ( image->type )
241
-		return 0;
242
-
243
-	/* Try each type in turn */
244
-	for_each_table_entry ( type, IMAGE_TYPES ) {
245
-		if ( ( rc = type->probe ( image ) ) == 0 ) {
246
-			image->type = type;
247
-			DBGC ( image, "IMAGE %s is %s\n",
248
-			       image->name, type->name );
249
-			return 0;
250
-		}
251
-		DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
252
-		       type->name, strerror ( rc ) );
253
-	}
254
-
255
-	DBGC ( image, "IMAGE %s format not recognised\n", image->name );
256
-	return -ENOEXEC;
257
-}
258
-
259
 /**
263
 /**
260
  * Execute image
264
  * Execute image
261
  *
265
  *
288
 	 */
292
 	 */
289
 	current_image = image_get ( image );
293
 	current_image = image_get ( image );
290
 
294
 
291
-	/* Check that this image can be selected for execution */
292
-	if ( ( rc = image_select ( image ) ) != 0 )
295
+	/* Check that this image can be executed */
296
+	if ( ! ( image->type && image->type->exec ) ) {
297
+		rc = -ENOEXEC;
293
 		goto err;
298
 		goto err;
299
+	}
294
 
300
 
295
 	/* Check that image is trusted (if applicable) */
301
 	/* Check that image is trusted (if applicable) */
296
 	if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
302
 	if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
382
 	}
388
 	}
383
 
389
 
384
 	/* Check that the replacement image can be executed */
390
 	/* Check that the replacement image can be executed */
385
-	if ( ( rc = image_probe ( replacement ) ) != 0 )
386
-		return rc;
391
+	if ( ! ( replacement->type && replacement->type->exec ) )
392
+		return -ENOEXEC;
387
 
393
 
388
 	/* Clear any existing replacement */
394
 	/* Clear any existing replacement */
389
 	image_put ( image->replacement );
395
 	image_put ( image->replacement );
404
  */
410
  */
405
 int image_select ( struct image *image ) {
411
 int image_select ( struct image *image ) {
406
 	struct image *tmp;
412
 	struct image *tmp;
407
-	int rc;
408
 
413
 
409
 	/* Unselect all other images */
414
 	/* Unselect all other images */
410
 	for_each_image ( tmp )
415
 	for_each_image ( tmp )
411
 		tmp->flags &= ~IMAGE_SELECTED;
416
 		tmp->flags &= ~IMAGE_SELECTED;
412
 
417
 
413
 	/* Check that this image can be executed */
418
 	/* Check that this image can be executed */
414
-	if ( ( rc = image_probe ( image ) ) != 0 )
415
-		return rc;
416
-	if ( ! image->type->exec )
419
+	if ( ! ( image->type && image->type->exec ) )
417
 		return -ENOEXEC;
420
 		return -ENOEXEC;
418
 
421
 
419
 	/* Mark image as selected */
422
 	/* Mark image as selected */
472
 	int rc;
475
 	int rc;
473
 
476
 
474
 	/* Check that this image can be used to create a pixel buffer */
477
 	/* Check that this image can be used to create a pixel buffer */
475
-	if ( ( rc = image_probe ( image ) ) != 0 )
476
-		return rc;
477
-	if ( ! image->type->pixbuf )
478
+	if ( ! ( image->type && image->type->pixbuf ) )
478
 		return -ENOTSUP;
479
 		return -ENOTSUP;
479
 
480
 
480
 	/* Try creating pixel buffer */
481
 	/* Try creating pixel buffer */

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

163
 extern int register_image ( struct image *image );
163
 extern int register_image ( struct image *image );
164
 extern void unregister_image ( struct image *image );
164
 extern void unregister_image ( struct image *image );
165
 struct image * find_image ( const char *name );
165
 struct image * find_image ( const char *name );
166
-extern int image_probe ( struct image *image );
167
 extern int image_exec ( struct image *image );
166
 extern int image_exec ( struct image *image );
168
 extern int image_replace ( struct image *replacement );
167
 extern int image_replace ( struct image *replacement );
169
 extern int image_select ( struct image *image );
168
 extern int image_select ( struct image *image );

+ 5
- 2
src/tests/pixbuf_test.c View File

57
 	/* Correct image data pointer */
57
 	/* Correct image data pointer */
58
 	test->image->data = virt_to_user ( ( void * ) test->image->data );
58
 	test->image->data = virt_to_user ( ( void * ) test->image->data );
59
 
59
 
60
-	/* Check that image is detected as PNM */
61
-	okx ( image_probe ( test->image ) == 0, file, line );
60
+	/* Check that image is detected as correct type */
61
+	okx ( register_image ( test->image ) == 0, file, line );
62
 	okx ( test->image->type == test->type, file, line );
62
 	okx ( test->image->type == test->type, file, line );
63
 
63
 
64
 	/* Check that a pixel buffer can be created from the image */
64
 	/* Check that a pixel buffer can be created from the image */
77
 
77
 
78
 		pixbuf_put ( pixbuf );
78
 		pixbuf_put ( pixbuf );
79
 	}
79
 	}
80
+
81
+	/* Unregister image */
82
+	unregister_image ( test->image );
80
 }
83
 }

Loading…
Cancel
Save