mirror of https://github.com/ipxe/ipxe.git
[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>
pull/54/head
parent
f58ebbdfb5
commit
abfe94a90a
|
@ -157,6 +157,32 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine image type
|
||||
*
|
||||
* @v image Executable image
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int image_probe ( struct image *image ) {
|
||||
struct image_type *type;
|
||||
int rc;
|
||||
|
||||
/* Try each type in turn */
|
||||
for_each_table_entry ( type, IMAGE_TYPES ) {
|
||||
if ( ( rc = type->probe ( image ) ) == 0 ) {
|
||||
image->type = type;
|
||||
DBGC ( image, "IMAGE %s is %s\n",
|
||||
image->name, type->name );
|
||||
break;
|
||||
}
|
||||
DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
|
||||
type->name, strerror ( rc ) );
|
||||
}
|
||||
|
||||
DBGC ( image, "IMAGE %s format not recognised\n", image->name );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register executable image
|
||||
*
|
||||
|
@ -189,6 +215,14 @@ int register_image ( struct image *image ) {
|
|||
image->name, user_to_phys ( image->data, 0 ),
|
||||
user_to_phys ( image->data, image->len ) );
|
||||
|
||||
/* Try to detect image type, if applicable. Ignore failures,
|
||||
* since we expect to handle some unrecognised images
|
||||
* (e.g. kernel initrds, multiboot modules, random files
|
||||
* provided via our EFI virtual filesystem, etc).
|
||||
*/
|
||||
if ( ! image->type )
|
||||
image_probe ( image );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -226,36 +260,6 @@ struct image * find_image ( const char *name ) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine image type
|
||||
*
|
||||
* @v image Executable image
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int image_probe ( struct image *image ) {
|
||||
struct image_type *type;
|
||||
int rc;
|
||||
|
||||
/* Succeed if we already have a type */
|
||||
if ( image->type )
|
||||
return 0;
|
||||
|
||||
/* Try each type in turn */
|
||||
for_each_table_entry ( type, IMAGE_TYPES ) {
|
||||
if ( ( rc = type->probe ( image ) ) == 0 ) {
|
||||
image->type = type;
|
||||
DBGC ( image, "IMAGE %s is %s\n",
|
||||
image->name, type->name );
|
||||
return 0;
|
||||
}
|
||||
DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
|
||||
type->name, strerror ( rc ) );
|
||||
}
|
||||
|
||||
DBGC ( image, "IMAGE %s format not recognised\n", image->name );
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute image
|
||||
*
|
||||
|
@ -288,9 +292,11 @@ int image_exec ( struct image *image ) {
|
|||
*/
|
||||
current_image = image_get ( image );
|
||||
|
||||
/* Check that this image can be selected for execution */
|
||||
if ( ( rc = image_select ( image ) ) != 0 )
|
||||
/* Check that this image can be executed */
|
||||
if ( ! ( image->type && image->type->exec ) ) {
|
||||
rc = -ENOEXEC;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Check that image is trusted (if applicable) */
|
||||
if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
|
||||
|
@ -382,8 +388,8 @@ int image_replace ( struct image *replacement ) {
|
|||
}
|
||||
|
||||
/* Check that the replacement image can be executed */
|
||||
if ( ( rc = image_probe ( replacement ) ) != 0 )
|
||||
return rc;
|
||||
if ( ! ( replacement->type && replacement->type->exec ) )
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Clear any existing replacement */
|
||||
image_put ( image->replacement );
|
||||
|
@ -404,16 +410,13 @@ int image_replace ( struct image *replacement ) {
|
|||
*/
|
||||
int image_select ( struct image *image ) {
|
||||
struct image *tmp;
|
||||
int rc;
|
||||
|
||||
/* Unselect all other images */
|
||||
for_each_image ( tmp )
|
||||
tmp->flags &= ~IMAGE_SELECTED;
|
||||
|
||||
/* Check that this image can be executed */
|
||||
if ( ( rc = image_probe ( image ) ) != 0 )
|
||||
return rc;
|
||||
if ( ! image->type->exec )
|
||||
if ( ! ( image->type && image->type->exec ) )
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Mark image as selected */
|
||||
|
@ -472,9 +475,7 @@ int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
|||
int rc;
|
||||
|
||||
/* Check that this image can be used to create a pixel buffer */
|
||||
if ( ( rc = image_probe ( image ) ) != 0 )
|
||||
return rc;
|
||||
if ( ! image->type->pixbuf )
|
||||
if ( ! ( image->type && image->type->pixbuf ) )
|
||||
return -ENOTSUP;
|
||||
|
||||
/* Try creating pixel buffer */
|
||||
|
|
|
@ -163,7 +163,6 @@ extern int image_set_cmdline ( struct image *image, const char *cmdline );
|
|||
extern int register_image ( struct image *image );
|
||||
extern void unregister_image ( struct image *image );
|
||||
struct image * find_image ( const char *name );
|
||||
extern int image_probe ( struct image *image );
|
||||
extern int image_exec ( struct image *image );
|
||||
extern int image_replace ( struct image *replacement );
|
||||
extern int image_select ( struct image *image );
|
||||
|
|
|
@ -57,8 +57,8 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file,
|
|||
/* Correct image data pointer */
|
||||
test->image->data = virt_to_user ( ( void * ) test->image->data );
|
||||
|
||||
/* Check that image is detected as PNM */
|
||||
okx ( image_probe ( test->image ) == 0, file, line );
|
||||
/* Check that image is detected as correct type */
|
||||
okx ( register_image ( test->image ) == 0, file, line );
|
||||
okx ( test->image->type == test->type, file, line );
|
||||
|
||||
/* Check that a pixel buffer can be created from the image */
|
||||
|
@ -77,4 +77,7 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file,
|
|||
|
||||
pixbuf_put ( pixbuf );
|
||||
}
|
||||
|
||||
/* Unregister image */
|
||||
unregister_image ( test->image );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue