]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[image] Add "--autofree" option
authorMichael Brown <mcb30@ipxe.org>
Fri, 20 Jul 2012 09:37:24 +0000 (10:37 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 20 Jul 2012 11:44:40 +0000 (12:44 +0100)
Allow images to be automatically freed after execution completes
(successfully or otherwise).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/image.c
src/hci/commands/image_cmd.c
src/include/ipxe/image.h
src/usr/imgmgmt.c

index bf9bb7fae5183023d7a1f773e057c1ee35f171c4..666ee3de8676323ba319fa0ef942c870eb197ca0 100644 (file)
@@ -194,6 +194,10 @@ int register_image ( struct image *image ) {
  */
 void unregister_image ( struct image *image ) {
 
+       /* Do nothing unless image is registered */
+       if ( ! ( image->flags & IMAGE_REGISTERED ) )
+               return;
+
        DBGC ( image, "IMAGE %s unregistered\n", image->name );
        list_del ( &image->list );
        image->flags &= ~IMAGE_REGISTERED;
@@ -259,23 +263,13 @@ int image_probe ( struct image *image ) {
  */
 int image_exec ( struct image *image ) {
        struct image *saved_current_image;
-       struct image *replacement;
+       struct image *replacement = NULL;
        struct uri *old_cwuri;
        int rc;
 
        /* Sanity check */
        assert ( image->flags & IMAGE_REGISTERED );
 
-       /* Check that this image can be selected for execution */
-       if ( ( rc = image_select ( image ) ) != 0 )
-               return rc;
-
-       /* Check that image is trusted (if applicable) */
-       if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
-               DBGC ( image, "IMAGE %s is not trusted\n", image->name );
-               return -EACCES_UNTRUSTED;
-       }
-
        /* Switch current working directory to be that of the image itself */
        old_cwuri = uri_get ( cwuri );
        churi ( image->uri );
@@ -289,6 +283,17 @@ 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 )
+               goto err;
+
+       /* Check that image is trusted (if applicable) */
+       if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
+               DBGC ( image, "IMAGE %s is not trusted\n", image->name );
+               rc = -EACCES_UNTRUSTED;
+               goto err;
+       }
+
        /* Record boot attempt */
        syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );
 
@@ -317,6 +322,11 @@ int image_exec ( struct image *image ) {
        if ( replacement )
                assert ( replacement->flags & IMAGE_REGISTERED );
 
+ err:
+       /* Unregister image if applicable */
+       if ( image->flags & IMAGE_AUTO_UNREGISTER )
+               unregister_image ( image );
+
        /* Drop temporary reference to the original image */
        image_put ( image );
 
index 1ae3307402275d131727c45afe0a6d23ec67bf5a..38d814cde1f58f5a738adac8ce062ded864fc379 100644 (file)
@@ -38,19 +38,24 @@ FILE_LICENCE ( GPL2_OR_LATER );
 struct imgsingle_options {
        /** Image name */
        const char *name;
+       /** Free image after execution */
+       int autofree;
 };
 
 /** "img{single}" option list */
 static struct option_descriptor imgsingle_opts[] = {
        OPTION_DESC ( "name", 'n', required_argument,
                      struct imgsingle_options, name, parse_string ),
+       OPTION_DESC ( "autofree", 'a', no_argument,
+                     struct imgsingle_options, autofree, parse_flag ),
 };
 
 /** "img{single}" command descriptor */
 static struct command_descriptor imgsingle_cmd =
        COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
                       1, MAX_ARGUMENTS,
-                      "[--name <name>] <uri|image> [<arguments>...]" );
+                      "[--name <name>] [--autofree] "
+                      "<uri|image> [<arguments>...]" );
 
 /** An "img{single}" family command descriptor */
 struct imgsingle_descriptor {
@@ -134,6 +139,10 @@ static int imgsingle_exec ( int argc, char **argv,
                }
        }
 
+       /* Set the auto-unregister flag, if applicable */
+       if ( opts.autofree )
+               image->flags |= IMAGE_AUTO_UNREGISTER;
+
        /* Carry out command action, if applicable */
        if ( desc->action ) {
                if ( ( rc = desc->action ( image ) ) != 0 ) {
@@ -160,7 +169,7 @@ static int imgsingle_exec ( int argc, char **argv,
 static struct command_descriptor imgfetch_cmd =
        COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
                       1, MAX_ARGUMENTS,
-                      "[--name <name>] <uri> [<arguments>...]" );
+                      "[--name <name>] [--autofree] <uri> [<arguments>...]" );
 
 /** "imgfetch" family command descriptor */
 struct imgsingle_descriptor imgfetch_desc = {
@@ -202,7 +211,7 @@ static int imgselect_exec ( int argc, char **argv ) {
 static struct command_descriptor imgexec_cmd =
        COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
                       0, MAX_ARGUMENTS,
-                      "[--name <name>] [<uri|image> [<arguments>...]]" );
+                      "[--autofree] [<uri|image> [<arguments>...]]" );
 
 /** "imgexec" family command descriptor */
 struct imgsingle_descriptor imgexec_desc = {
index ac97137bd38322e03cec76de58f5291e59878fb2..6022dce66b22f15d900af23f69b4f507c4c35b86 100644 (file)
@@ -67,6 +67,9 @@ struct image {
 /** Image is trusted */
 #define IMAGE_TRUSTED 0x0004
 
+/** Image will be automatically unregistered after execution */
+#define IMAGE_AUTO_UNREGISTER 0x0008
+
 /** An executable image type */
 struct image_type {
        /** Name of this image type */
index 2c74f4867ec672a4becfe4fb1467205072cb8bff..ce3bc90fb3211494deb9e9b0c6dcf9b9ea499932 100644 (file)
@@ -146,6 +146,8 @@ void imgstat ( struct image *image ) {
                printf ( " [TRUSTED]" );
        if ( image->flags & IMAGE_SELECTED )
                printf ( " [SELECTED]" );
+       if ( image->flags & IMAGE_AUTO_UNREGISTER )
+               printf ( " [AUTOFREE]" );
        if ( image->cmdline )
                printf ( " \"%s\"", image->cmdline );
        printf ( "\n" );