diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/image.c | 59 | ||||
| -rw-r--r-- | src/include/gpxe/image.h | 2 | ||||
| -rw-r--r-- | src/usr/imgmgmt.c | 16 |
3 files changed, 47 insertions, 30 deletions
diff --git a/src/core/image.c b/src/core/image.c index be0eecf98..6f54be115 100644 --- a/src/core/image.c +++ b/src/core/image.c @@ -23,6 +23,7 @@ #include <assert.h> #include <vsprintf.h> #include <gpxe/list.h> +#include <gpxe/emalloc.h> #include <gpxe/image.h> /** @file @@ -73,6 +74,20 @@ void unregister_image ( struct image *image ) { } /** + * Move image to start of list of registered images + * + * @v image Executable/loadable image + * + * Move the image to the start of the image list. This makes it + * easier to keep track of which of the images marked as loaded is + * likely to still be valid. + */ +void promote_image ( struct image *image ) { + list_del ( &image->list ); + list_add ( &image->list, &images ); +} + +/** * Find image by name * * @v name Image name @@ -90,18 +105,24 @@ struct image * find_image ( const char *name ) { } /** - * Free loaded image + * Load executable/loadable image into memory * * @v image Executable/loadable image - * - * This releases the memory being used to store the image; it does not - * release the @c struct @c image itself, nor does it unregister the - * image. + * @v type Executable/loadable image type + * @ret rc Return status code */ -void free_image ( struct image *image ) { - efree ( image->data ); - image->data = UNULL; - image->len = 0; +static int image_load_type ( struct image *image, struct image_type *type ) { + int rc; + + if ( ( rc = type->load ( image ) ) != 0 ) { + DBGC ( image, "IMAGE %p could not load as %s: %s\n", + image, type->name, strerror ( rc ) ); + return rc; + } + + /* Flag as loaded */ + image->flags |= IMAGE_LOADED; + return 0; } /** @@ -111,18 +132,10 @@ void free_image ( struct image *image ) { * @ret rc Return status code */ int image_load ( struct image *image ) { - int rc; assert ( image->type != NULL ); - if ( ( rc = image->type->load ( image ) ) != 0 ) { - DBGC ( image, "IMAGE %p could not load: %s\n", - image, strerror ( rc ) ); - return rc; - } - - image->flags |= IMAGE_LOADED; - return 0; + return image_load_type ( image, image->type ); } /** @@ -137,16 +150,10 @@ int image_autoload ( struct image *image ) { for ( type = image_types ; type < image_types_end ; type++ ) { DBGC ( image, "IMAGE %p trying type %s\n", image, type->name ); - rc = type->load ( image ); + rc = image_load_type ( image, type ); if ( image->type == NULL ) continue; - if ( rc != 0 ) { - DBGC ( image, "IMAGE %p (%s) could not load: %s\n", - image, image->type->name, strerror ( rc ) ); - return rc; - } - image->flags |= IMAGE_LOADED; - return 0; + return rc; } DBGC ( image, "IMAGE %p format not recognised\n", image ); diff --git a/src/include/gpxe/image.h b/src/include/gpxe/image.h index e00771fff..de10c369e 100644 --- a/src/include/gpxe/image.h +++ b/src/include/gpxe/image.h @@ -107,8 +107,8 @@ extern struct list_head images; extern int register_image ( struct image *image ); extern void unregister_image ( struct image *image ); +extern void promote_image ( struct image *image ); struct image * find_image ( const char *name ); -extern void free_image ( struct image *image ); extern int image_load ( struct image *image ); extern int image_autoload ( struct image *image ); extern int image_exec ( struct image *image ); diff --git a/src/usr/imgmgmt.c b/src/usr/imgmgmt.c index 6a2599d53..eb2330a33 100644 --- a/src/usr/imgmgmt.c +++ b/src/usr/imgmgmt.c @@ -21,6 +21,7 @@ #include <errno.h> #include <vsprintf.h> #include <gpxe/image.h> +#include <gpxe/emalloc.h> #include <usr/fetch.h> #include <usr/imgmgmt.h> @@ -65,7 +66,7 @@ int imgfetch ( const char *filename, const char *name, return 0; err: - free_image ( image ); + efree ( image->data ); free ( image ); return rc; } @@ -77,7 +78,16 @@ int imgfetch ( const char *filename, const char *name, * @ret rc Return status code */ int imgload ( struct image *image ) { - return image_autoload ( image ); + int rc; + + /* Try to load image */ + if ( ( rc = image_autoload ( image ) ) != 0 ) + return rc; + + /* If we succeed, move the image to the start of the list */ + promote_image ( image ); + + return 0; } /** @@ -129,6 +139,6 @@ void imgstat ( struct image *image ) { */ void imgfree ( struct image *image ) { unregister_image ( image ); - free_image ( image ); + efree ( image->data ); free ( image ); } |
