summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2017-07-17 15:25:10 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-07-21 09:26:37 +0100
commitc8f64501ad9198572d0a7815928068989ccff556 (patch)
tree9eac07d904ccc3b4b4e456b9e48ee2ae889e804f
parent882e85cd83affed95b747473b248aba99ccd25d6 (diff)
downloadpoky-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.py14
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
30import subprocess 30import subprocess
31import os 31import os
32import logging 32import logging
33import errno
33import bb 34import bb
34import bb.progress 35import bb.progress
35import urllib.request, urllib.parse, urllib.error 36import 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: