summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/image.c59
-rw-r--r--src/include/gpxe/image.h2
-rw-r--r--src/usr/imgmgmt.c16
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 );
}