diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2017-07-17 15:25:10 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-07-21 09:26:37 +0100 |
commit | c8f64501ad9198572d0a7815928068989ccff556 (patch) | |
tree | 9eac07d904ccc3b4b4e456b9e48ee2ae889e804f | |
parent | 882e85cd83affed95b747473b248aba99ccd25d6 (diff) | |
download | poky-c8f64501ad9198572d0a7815928068989ccff556.tar.gz |
bitbake: fetch2/wget.py: improve error handling during sstate check
When the sstate is accessed via HTTP, the existence check can fail due
to network issues, in which case bitbake silently continues without
sstate.
One such network issue is an HTTP server like Python's own SimpleHTTP
which closes the TCP connection despite an explicit "Keep-Alive" in
the HTTP request header. The server does that without a "close" in the
HTTP response header, so the socket remains in the connection cache,
leading to "urlopen failed: <urlopen error [Errno 9] Bad file
descriptor>" (only visible in "bitbake -D -D" output) when trying to
use the cached connection again.
The connection might also get closed for other reasons (proxy,
timeouts, etc.), so this is something that the client should be able
to handle.
This is achieved by checking for the error, removing the bad
connection, and letting the check_status() method try again with a new
connection. It is necessary to let the second attempt fail
permanently, because bad proxy setups have been observed to also lead
to such broken connections. In that case, we need to abort for real
after trying twice, otherwise a build would just hang forever.
[YOCTO #11782]
(Bitbake rev: 6fa07752bbd3ac345cd8617da49a70e0b2dd565f)
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | bitbake/lib/bb/fetch2/wget.py | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/bitbake/lib/bb/fetch2/wget.py b/bitbake/lib/bb/fetch2/wget.py index ae0ffa8c97..208ee9bdd6 100644 --- a/bitbake/lib/bb/fetch2/wget.py +++ b/bitbake/lib/bb/fetch2/wget.py | |||
@@ -30,6 +30,7 @@ import tempfile | |||
30 | import subprocess | 30 | import subprocess |
31 | import os | 31 | import os |
32 | import logging | 32 | import logging |
33 | import errno | ||
33 | import bb | 34 | import bb |
34 | import bb.progress | 35 | import bb.progress |
35 | import urllib.request, urllib.parse, urllib.error | 36 | import urllib.request, urllib.parse, urllib.error |
@@ -206,8 +207,21 @@ class Wget(FetchMethod): | |||
206 | h.request(req.get_method(), req.selector, req.data, headers) | 207 | h.request(req.get_method(), req.selector, req.data, headers) |
207 | except socket.error as err: # XXX what error? | 208 | except socket.error as err: # XXX what error? |
208 | # Don't close connection when cache is enabled. | 209 | # Don't close connection when cache is enabled. |
210 | # Instead, try to detect connections that are no longer | ||
211 | # usable (for example, closed unexpectedly) and remove | ||
212 | # them from the cache. | ||
209 | if fetch.connection_cache is None: | 213 | if fetch.connection_cache is None: |
210 | h.close() | 214 | h.close() |
215 | elif isinstance(err, OSError) and err.errno == errno.EBADF: | ||
216 | # This happens when the server closes the connection despite the Keep-Alive. | ||
217 | # Apparently urllib then uses the file descriptor, expecting it to be | ||
218 | # connected, when in reality the connection is already gone. | ||
219 | # We let the request fail and expect it to be | ||
220 | # tried once more ("try_again" in check_status()), | ||
221 | # with the dead connection removed from the cache. | ||
222 | # If it still fails, we give up, which can happend for bad | ||
223 | # HTTP proxy settings. | ||
224 | fetch.connection_cache.remove_connection(h.host, h.port) | ||
211 | raise urllib.error.URLError(err) | 225 | raise urllib.error.URLError(err) |
212 | else: | 226 | else: |
213 | try: | 227 | try: |