]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[image] Add "--timeout" parameter to image downloading commands
authorMichael Brown <mcb30@ipxe.org>
Mon, 10 Mar 2014 13:32:39 +0000 (13:32 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 10 Mar 2014 13:32:39 +0000 (13:32 +0000)
iPXE will detect timeout failures in several situations: network
link-up, DHCP, TCP connection attempts, unacknowledged TCP data, etc.
This does not cover all possible circumstances.  For example, if a
connection to a web server is successfully established and the web
server acknowledges the HTTP request but never sends any data in
response, then no timeout will be triggered.  There is no timeout
defined within the HTTP specifications, and the underlying TCP
connection will not generate a timeout since it has no way to know
that the HTTP layer is expecting to receive data from the server.

Add a "--timeout" parameter to "imgfetch", "chain", etc.  If no
progress is made (i.e. no data is downloaded) within the timeout
period, then the download will be aborted.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/interface/syslinux/comboot_call.c
src/hci/commands/console_cmd.c
src/hci/commands/digest_cmd.c
src/hci/commands/image_cmd.c
src/hci/commands/image_trust_cmd.c
src/include/usr/imgmgmt.h
src/usr/autoboot.c
src/usr/imgmgmt.c

index fbf605f3348a80dcd9dd331b39145cb7f7763478..1854501def99482e1dee7cde418a51680a265417 100644 (file)
@@ -188,7 +188,8 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
                DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file );
 
                /* Fetch initrd */
-               if ( ( rc = imgdownload_string ( initrd_file, &initrd ) ) != 0){
+               if ( ( rc = imgdownload_string ( initrd_file, 0,
+                                                &initrd ) ) != 0 ) {
                        DBG ( "COMBOOT: could not fetch initrd: %s\n",
                              strerror ( rc ) );
                        return rc;
@@ -202,7 +203,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
        DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
 
        /* Fetch kernel */
-       if ( ( rc = imgdownload_string ( kernel_file, &kernel ) ) != 0 ) {
+       if ( ( rc = imgdownload_string ( kernel_file, 0, &kernel ) ) != 0 ) {
                DBG ( "COMBOOT: could not fetch kernel: %s\n",
                      strerror ( rc ) );
                return rc;
index db4136868c3cb714d63fbdf5d8fffcd6de42a3ee..d2eae59f0515ab74037995202b044144dd6ea12a 100644 (file)
@@ -92,7 +92,7 @@ static int console_exec ( int argc, char **argv ) {
        if ( opts.picture ) {
 
                /* Acquire image */
-               if ( ( rc = imgacquire ( opts.picture, &image ) ) != 0 )
+               if ( ( rc = imgacquire ( opts.picture, 0, &image ) ) != 0 )
                        goto err_acquire;
 
                /* Convert to pixel buffer */
index 3cf2f10267de1529cce1c48dca842b054f685a64..71308064fb9c7eb91497d8d7cf6627069e39b7ef 100644 (file)
@@ -77,7 +77,7 @@ static int digest_exec ( int argc, char **argv,
        for ( i = optind ; i < argc ; i++ ) {
 
                /* Acquire image */
-               if ( ( rc = imgacquire ( argv[i], &image ) ) != 0 )
+               if ( ( rc = imgacquire ( argv[i], 0, &image ) ) != 0 )
                        continue;
                offset = 0;
                len = image->len;
index dc30b3f2478b06a2b36f02afe814a6b7a5e8870c..a9e831bf507c1e0aad186b8c211a472885a12f9a 100644 (file)
@@ -40,6 +40,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 struct imgsingle_options {
        /** Image name */
        char *name;
+       /** Download timeout */
+       unsigned long timeout;
        /** Replace image */
        int replace;
        /** Free image after execution */
@@ -49,13 +51,17 @@ struct imgsingle_options {
 /** "img{single}" option list */
 static union {
        /* "imgexec" takes all three options */
-       struct option_descriptor imgexec[3];
-       /* Other "img{single}" commands take only --name and --autofree */
-       struct option_descriptor imgsingle[2];
+       struct option_descriptor imgexec[4];
+       /* Other "img{single}" commands take only --name, --timeout,
+        * and --autofree
+        */
+       struct option_descriptor imgsingle[3];
 } opts = {
        .imgexec = {
                OPTION_DESC ( "name", 'n', required_argument,
                              struct imgsingle_options, name, parse_string ),
+               OPTION_DESC ( "timeout", 't', required_argument,
+                             struct imgsingle_options, timeout, parse_timeout),
                OPTION_DESC ( "autofree", 'a', no_argument,
                              struct imgsingle_options, autofree, parse_flag ),
                OPTION_DESC ( "replace", 'r', no_argument,
@@ -68,7 +74,8 @@ struct imgsingle_descriptor {
        /** Command descriptor */
        struct command_descriptor *cmd;
        /** Function to use to acquire the image */
-       int ( * acquire ) ( const char *name, struct image **image );
+       int ( * acquire ) ( const char *name, unsigned long timeout,
+                           struct image **image );
        /** Pre-action to take upon image, or NULL */
        void ( * preaction ) ( struct image *image );
        /** Action to take upon image, or NULL */
@@ -114,7 +121,8 @@ static int imgsingle_exec ( int argc, char **argv,
 
        /* Acquire the image */
        if ( name_uri ) {
-               if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
+               if ( ( rc = desc->acquire ( name_uri, opts.timeout,
+                                           &image ) ) != 0 )
                        goto err_acquire;
        } else {
                image = image_find_selected();
index ef4bbfa898c961c2f16bc53d2501c5333f652b68..ca59a858ae6d3df05879f8d5166d217a88187c09 100644 (file)
@@ -86,6 +86,8 @@ struct imgverify_options {
        char *signer;
        /** Keep signature after verification */
        int keep;
+       /** Download timeout */
+       unsigned long timeout;
 };
 
 /** "imgverify" option list */
@@ -94,6 +96,8 @@ static struct option_descriptor imgverify_opts[] = {
                      struct imgverify_options, signer, parse_string ),
        OPTION_DESC ( "keep", 'k', no_argument,
                      struct imgverify_options, keep, parse_flag ),
+       OPTION_DESC ( "timeout", 't', required_argument,
+                     struct imgverify_options, timeout, parse_timeout),
 };
 
 /** "imgverify" command descriptor */
@@ -127,11 +131,12 @@ static int imgverify_exec ( int argc, char **argv ) {
        signature_name_uri = argv[ optind + 1 ];
 
        /* Acquire the image */
-       if ( ( rc = imgacquire ( image_name_uri, &image ) ) != 0 )
+       if ( ( rc = imgacquire ( image_name_uri, opts.timeout, &image ) ) != 0 )
                goto err_acquire_image;
 
        /* Acquire the signature image */
-       if ( ( rc = imgacquire ( signature_name_uri, &signature ) ) != 0 )
+       if ( ( rc = imgacquire ( signature_name_uri, opts.timeout,
+                                &signature ) ) != 0 )
                goto err_acquire_signature;
 
        /* Verify image */
index 8db5c9780f59c1ab6db569c8eb0d9d954c614660..5e25c562bdb57d29564ba69188c3919b5eb3f90f 100644 (file)
@@ -11,9 +11,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
 
 #include <ipxe/image.h>
 
-extern int imgdownload ( struct uri *uri, struct image **image );
-extern int imgdownload_string ( const char *uri_string, struct image **image );
-extern int imgacquire ( const char *name, struct image **image );
+extern int imgdownload ( struct uri *uri, unsigned long timeout,
+                        struct image **image );
+extern int imgdownload_string ( const char *uri_string, unsigned long timeout,
+                               struct image **image );
+extern int imgacquire ( const char *name, unsigned long timeout,
+                       struct image **image );
 extern void imgstat ( struct image *image );
 
 #endif /* _USR_IMGMGMT_H */
index c9012f21d59c2db79dfdd3131259259514c658e0..af3d1f7bb00e34edf6c066ce48889b7fadde09f9 100644 (file)
@@ -165,7 +165,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
 
        /* Attempt filename boot if applicable */
        if ( filename ) {
-               if ( ( rc = imgdownload ( filename, &image ) ) != 0 )
+               if ( ( rc = imgdownload ( filename, 0, &image ) ) != 0 )
                        goto err_download;
                image->flags |= IMAGE_AUTO_UNREGISTER;
                if ( ( rc = image_exec ( image ) ) != 0 ) {
index 18cabbbc69a8b59182dafceb16bb802593e3c589..c9c5716400e9d4a25e32ce14de2ce701f0c055c3 100644 (file)
@@ -40,10 +40,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
  * Download a new image
  *
  * @v uri              URI
+ * @v timeout          Download timeout
  * @v image            Image to fill in
  * @ret rc             Return status code
  */
-int imgdownload ( struct uri *uri, struct image **image ) {
+int imgdownload ( struct uri *uri, unsigned long timeout,
+                 struct image **image ) {
        const char *password;
        char *uri_string_redacted;
        int rc;
@@ -80,7 +82,7 @@ int imgdownload ( struct uri *uri, struct image **image ) {
        }
 
        /* Wait for download to complete */
-       if ( ( rc = monojob_wait ( uri_string_redacted, 0 ) ) != 0 )
+       if ( ( rc = monojob_wait ( uri_string_redacted, timeout ) ) != 0 )
                goto err_monojob_wait;
 
        /* Register image */
@@ -105,17 +107,19 @@ int imgdownload ( struct uri *uri, struct image **image ) {
  * Download a new image
  *
  * @v uri_string       URI string
+ * @v timeout          Download timeout
  * @v image            Image to fill in
  * @ret rc             Return status code
  */
-int imgdownload_string ( const char *uri_string, struct image **image ) {
+int imgdownload_string ( const char *uri_string, unsigned long timeout,
+                        struct image **image ) {
        struct uri *uri;
        int rc;
 
        if ( ! ( uri = parse_uri ( uri_string ) ) )
                return -ENOMEM;
 
-       rc = imgdownload ( uri, image );
+       rc = imgdownload ( uri, timeout, image );
 
        uri_put ( uri );
        return rc;
@@ -125,10 +129,12 @@ int imgdownload_string ( const char *uri_string, struct image **image ) {
  * Acquire an image
  *
  * @v name_uri         Name or URI string
+ * @v timeout          Download timeout
  * @v image            Image to fill in
  * @ret rc             Return status code
  */
-int imgacquire ( const char *name_uri, struct image **image ) {
+int imgacquire ( const char *name_uri, unsigned long timeout,
+                struct image **image ) {
 
        /* If we already have an image with the specified name, use it */
        *image = find_image ( name_uri );
@@ -136,7 +142,7 @@ int imgacquire ( const char *name_uri, struct image **image ) {
                return 0;
 
        /* Otherwise, download a new image */
-       return imgdownload_string ( name_uri, image );
+       return imgdownload_string ( name_uri, timeout, image );
 }
 
 /**