Let ifmgmt.c take care of calling efree(), since it's the once which

took out the contract to eventually call efree() when it called fetch().

Maintain the most recently loaded image at the start of the list, so that
imgautoselect() will pick it.
pull/1/head
Michael Brown 2007-01-12 09:46:10 +00:00
parent 39ede8c7e8
commit e2c0055e23
3 changed files with 47 additions and 30 deletions

View File

@ -23,6 +23,7 @@
#include <assert.h> #include <assert.h>
#include <vsprintf.h> #include <vsprintf.h>
#include <gpxe/list.h> #include <gpxe/list.h>
#include <gpxe/emalloc.h>
#include <gpxe/image.h> #include <gpxe/image.h>
/** @file /** @file
@ -72,6 +73,20 @@ void unregister_image ( struct image *image ) {
DBGC ( image, "IMAGE %p unregistered\n", image ); DBGC ( image, "IMAGE %p unregistered\n", 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 * Find image by 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 * @v image Executable/loadable image
* * @v type Executable/loadable image type
* This releases the memory being used to store the image; it does not * @ret rc Return status code
* release the @c struct @c image itself, nor does it unregister the
* image.
*/ */
void free_image ( struct image *image ) { static int image_load_type ( struct image *image, struct image_type *type ) {
efree ( image->data ); int rc;
image->data = UNULL;
image->len = 0; 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 * @ret rc Return status code
*/ */
int image_load ( struct image *image ) { int image_load ( struct image *image ) {
int rc;
assert ( image->type != NULL ); assert ( image->type != NULL );
if ( ( rc = image->type->load ( image ) ) != 0 ) { return image_load_type ( image, image->type );
DBGC ( image, "IMAGE %p could not load: %s\n",
image, strerror ( rc ) );
return rc;
}
image->flags |= IMAGE_LOADED;
return 0;
} }
/** /**
@ -137,16 +150,10 @@ int image_autoload ( struct image *image ) {
for ( type = image_types ; type < image_types_end ; type++ ) { for ( type = image_types ; type < image_types_end ; type++ ) {
DBGC ( image, "IMAGE %p trying type %s\n", image, type->name ); 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 ) if ( image->type == NULL )
continue; continue;
if ( rc != 0 ) { return rc;
DBGC ( image, "IMAGE %p (%s) could not load: %s\n",
image, image->type->name, strerror ( rc ) );
return rc;
}
image->flags |= IMAGE_LOADED;
return 0;
} }
DBGC ( image, "IMAGE %p format not recognised\n", image ); DBGC ( image, "IMAGE %p format not recognised\n", image );

View File

@ -107,8 +107,8 @@ extern struct list_head images;
extern int register_image ( struct image *image ); extern int register_image ( struct image *image );
extern void unregister_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 ); struct image * find_image ( const char *name );
extern void free_image ( struct image *image );
extern int image_load ( struct image *image ); extern int image_load ( struct image *image );
extern int image_autoload ( struct image *image ); extern int image_autoload ( struct image *image );
extern int image_exec ( struct image *image ); extern int image_exec ( struct image *image );

View File

@ -21,6 +21,7 @@
#include <errno.h> #include <errno.h>
#include <vsprintf.h> #include <vsprintf.h>
#include <gpxe/image.h> #include <gpxe/image.h>
#include <gpxe/emalloc.h>
#include <usr/fetch.h> #include <usr/fetch.h>
#include <usr/imgmgmt.h> #include <usr/imgmgmt.h>
@ -65,7 +66,7 @@ int imgfetch ( const char *filename, const char *name,
return 0; return 0;
err: err:
free_image ( image ); efree ( image->data );
free ( image ); free ( image );
return rc; return rc;
} }
@ -77,7 +78,16 @@ int imgfetch ( const char *filename, const char *name,
* @ret rc Return status code * @ret rc Return status code
*/ */
int imgload ( struct image *image ) { 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 ) { void imgfree ( struct image *image ) {
unregister_image ( image ); unregister_image ( image );
free_image ( image ); efree ( image->data );
free ( image ); free ( image );
} }