Browse Source

[image] Add "--timeout" parameter to image downloading commands

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>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
3f43c1354e

+ 3
- 2
src/arch/i386/interface/syslinux/comboot_call.c View File

@@ -188,7 +188,8 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
188 188
 		DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file );
189 189
 
190 190
 		/* Fetch initrd */
191
-		if ( ( rc = imgdownload_string ( initrd_file, &initrd ) ) != 0){
191
+		if ( ( rc = imgdownload_string ( initrd_file, 0,
192
+						 &initrd ) ) != 0 ) {
192 193
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
193 194
 			      strerror ( rc ) );
194 195
 			return rc;
@@ -202,7 +203,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
202 203
 	DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file );
203 204
 
204 205
 	/* Fetch kernel */
205
-	if ( ( rc = imgdownload_string ( kernel_file, &kernel ) ) != 0 ) {
206
+	if ( ( rc = imgdownload_string ( kernel_file, 0, &kernel ) ) != 0 ) {
206 207
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
207 208
 		      strerror ( rc ) );
208 209
 		return rc;

+ 1
- 1
src/hci/commands/console_cmd.c View File

@@ -92,7 +92,7 @@ static int console_exec ( int argc, char **argv ) {
92 92
 	if ( opts.picture ) {
93 93
 
94 94
 		/* Acquire image */
95
-		if ( ( rc = imgacquire ( opts.picture, &image ) ) != 0 )
95
+		if ( ( rc = imgacquire ( opts.picture, 0, &image ) ) != 0 )
96 96
 			goto err_acquire;
97 97
 
98 98
 		/* Convert to pixel buffer */

+ 1
- 1
src/hci/commands/digest_cmd.c View File

@@ -77,7 +77,7 @@ static int digest_exec ( int argc, char **argv,
77 77
 	for ( i = optind ; i < argc ; i++ ) {
78 78
 
79 79
 		/* Acquire image */
80
-		if ( ( rc = imgacquire ( argv[i], &image ) ) != 0 )
80
+		if ( ( rc = imgacquire ( argv[i], 0, &image ) ) != 0 )
81 81
 			continue;
82 82
 		offset = 0;
83 83
 		len = image->len;

+ 13
- 5
src/hci/commands/image_cmd.c View File

@@ -40,6 +40,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
40 40
 struct imgsingle_options {
41 41
 	/** Image name */
42 42
 	char *name;
43
+	/** Download timeout */
44
+	unsigned long timeout;
43 45
 	/** Replace image */
44 46
 	int replace;
45 47
 	/** Free image after execution */
@@ -49,13 +51,17 @@ struct imgsingle_options {
49 51
 /** "img{single}" option list */
50 52
 static union {
51 53
 	/* "imgexec" takes all three options */
52
-	struct option_descriptor imgexec[3];
53
-	/* Other "img{single}" commands take only --name and --autofree */
54
-	struct option_descriptor imgsingle[2];
54
+	struct option_descriptor imgexec[4];
55
+	/* Other "img{single}" commands take only --name, --timeout,
56
+	 * and --autofree
57
+	 */
58
+	struct option_descriptor imgsingle[3];
55 59
 } opts = {
56 60
 	.imgexec = {
57 61
 		OPTION_DESC ( "name", 'n', required_argument,
58 62
 			      struct imgsingle_options, name, parse_string ),
63
+		OPTION_DESC ( "timeout", 't', required_argument,
64
+			      struct imgsingle_options, timeout, parse_timeout),
59 65
 		OPTION_DESC ( "autofree", 'a', no_argument,
60 66
 			      struct imgsingle_options, autofree, parse_flag ),
61 67
 		OPTION_DESC ( "replace", 'r', no_argument,
@@ -68,7 +74,8 @@ struct imgsingle_descriptor {
68 74
 	/** Command descriptor */
69 75
 	struct command_descriptor *cmd;
70 76
 	/** Function to use to acquire the image */
71
-	int ( * acquire ) ( const char *name, struct image **image );
77
+	int ( * acquire ) ( const char *name, unsigned long timeout,
78
+			    struct image **image );
72 79
 	/** Pre-action to take upon image, or NULL */
73 80
 	void ( * preaction ) ( struct image *image );
74 81
 	/** Action to take upon image, or NULL */
@@ -114,7 +121,8 @@ static int imgsingle_exec ( int argc, char **argv,
114 121
 
115 122
 	/* Acquire the image */
116 123
 	if ( name_uri ) {
117
-		if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
124
+		if ( ( rc = desc->acquire ( name_uri, opts.timeout,
125
+					    &image ) ) != 0 )
118 126
 			goto err_acquire;
119 127
 	} else {
120 128
 		image = image_find_selected();

+ 7
- 2
src/hci/commands/image_trust_cmd.c View File

@@ -86,6 +86,8 @@ struct imgverify_options {
86 86
 	char *signer;
87 87
 	/** Keep signature after verification */
88 88
 	int keep;
89
+	/** Download timeout */
90
+	unsigned long timeout;
89 91
 };
90 92
 
91 93
 /** "imgverify" option list */
@@ -94,6 +96,8 @@ static struct option_descriptor imgverify_opts[] = {
94 96
 		      struct imgverify_options, signer, parse_string ),
95 97
 	OPTION_DESC ( "keep", 'k', no_argument,
96 98
 		      struct imgverify_options, keep, parse_flag ),
99
+	OPTION_DESC ( "timeout", 't', required_argument,
100
+		      struct imgverify_options, timeout, parse_timeout),
97 101
 };
98 102
 
99 103
 /** "imgverify" command descriptor */
@@ -127,11 +131,12 @@ static int imgverify_exec ( int argc, char **argv ) {
127 131
 	signature_name_uri = argv[ optind + 1 ];
128 132
 
129 133
 	/* Acquire the image */
130
-	if ( ( rc = imgacquire ( image_name_uri, &image ) ) != 0 )
134
+	if ( ( rc = imgacquire ( image_name_uri, opts.timeout, &image ) ) != 0 )
131 135
 		goto err_acquire_image;
132 136
 
133 137
 	/* Acquire the signature image */
134
-	if ( ( rc = imgacquire ( signature_name_uri, &signature ) ) != 0 )
138
+	if ( ( rc = imgacquire ( signature_name_uri, opts.timeout,
139
+				 &signature ) ) != 0 )
135 140
 		goto err_acquire_signature;
136 141
 
137 142
 	/* Verify image */

+ 6
- 3
src/include/usr/imgmgmt.h View File

@@ -11,9 +11,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 #include <ipxe/image.h>
13 13
 
14
-extern int imgdownload ( struct uri *uri, struct image **image );
15
-extern int imgdownload_string ( const char *uri_string, struct image **image );
16
-extern int imgacquire ( const char *name, struct image **image );
14
+extern int imgdownload ( struct uri *uri, unsigned long timeout,
15
+			 struct image **image );
16
+extern int imgdownload_string ( const char *uri_string, unsigned long timeout,
17
+				struct image **image );
18
+extern int imgacquire ( const char *name, unsigned long timeout,
19
+			struct image **image );
17 20
 extern void imgstat ( struct image *image );
18 21
 
19 22
 #endif /* _USR_IMGMGMT_H */

+ 1
- 1
src/usr/autoboot.c View File

@@ -165,7 +165,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
165 165
 
166 166
 	/* Attempt filename boot if applicable */
167 167
 	if ( filename ) {
168
-		if ( ( rc = imgdownload ( filename, &image ) ) != 0 )
168
+		if ( ( rc = imgdownload ( filename, 0, &image ) ) != 0 )
169 169
 			goto err_download;
170 170
 		image->flags |= IMAGE_AUTO_UNREGISTER;
171 171
 		if ( ( rc = image_exec ( image ) ) != 0 ) {

+ 12
- 6
src/usr/imgmgmt.c View File

@@ -40,10 +40,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
40 40
  * Download a new image
41 41
  *
42 42
  * @v uri		URI
43
+ * @v timeout		Download timeout
43 44
  * @v image		Image to fill in
44 45
  * @ret rc		Return status code
45 46
  */
46
-int imgdownload ( struct uri *uri, struct image **image ) {
47
+int imgdownload ( struct uri *uri, unsigned long timeout,
48
+		  struct image **image ) {
47 49
 	const char *password;
48 50
 	char *uri_string_redacted;
49 51
 	int rc;
@@ -80,7 +82,7 @@ int imgdownload ( struct uri *uri, struct image **image ) {
80 82
 	}
81 83
 
82 84
 	/* Wait for download to complete */
83
-	if ( ( rc = monojob_wait ( uri_string_redacted, 0 ) ) != 0 )
85
+	if ( ( rc = monojob_wait ( uri_string_redacted, timeout ) ) != 0 )
84 86
 		goto err_monojob_wait;
85 87
 
86 88
 	/* Register image */
@@ -105,17 +107,19 @@ int imgdownload ( struct uri *uri, struct image **image ) {
105 107
  * Download a new image
106 108
  *
107 109
  * @v uri_string	URI string
110
+ * @v timeout		Download timeout
108 111
  * @v image		Image to fill in
109 112
  * @ret rc		Return status code
110 113
  */
111
-int imgdownload_string ( const char *uri_string, struct image **image ) {
114
+int imgdownload_string ( const char *uri_string, unsigned long timeout,
115
+			 struct image **image ) {
112 116
 	struct uri *uri;
113 117
 	int rc;
114 118
 
115 119
 	if ( ! ( uri = parse_uri ( uri_string ) ) )
116 120
 		return -ENOMEM;
117 121
 
118
-	rc = imgdownload ( uri, image );
122
+	rc = imgdownload ( uri, timeout, image );
119 123
 
120 124
 	uri_put ( uri );
121 125
 	return rc;
@@ -125,10 +129,12 @@ int imgdownload_string ( const char *uri_string, struct image **image ) {
125 129
  * Acquire an image
126 130
  *
127 131
  * @v name_uri		Name or URI string
132
+ * @v timeout		Download timeout
128 133
  * @v image		Image to fill in
129 134
  * @ret rc		Return status code
130 135
  */
131
-int imgacquire ( const char *name_uri, struct image **image ) {
136
+int imgacquire ( const char *name_uri, unsigned long timeout,
137
+		 struct image **image ) {
132 138
 
133 139
 	/* If we already have an image with the specified name, use it */
134 140
 	*image = find_image ( name_uri );
@@ -136,7 +142,7 @@ int imgacquire ( const char *name_uri, struct image **image ) {
136 142
 		return 0;
137 143
 
138 144
 	/* Otherwise, download a new image */
139
-	return imgdownload_string ( name_uri, image );
145
+	return imgdownload_string ( name_uri, timeout, image );
140 146
 }
141 147
 
142 148
 /**

Loading…
Cancel
Save