From 320ba554d11f75c4c2753968505a1d3308b64dda Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Mon, 25 Jun 2018 19:22:13 +0300 Subject: [PATCH] v2v: rvh-upload-plugin: Always read the response Python manual warns[1]: Note that you must have read the whole response before you can send a new request to the server. The reason for this warning is exposed only when the server is using keep alive connections. When the response is not read, sending a new request will fail with: httplib.ResponseNotReady Even if Content-Length was 0 or the request has no content. The failure looks like this when using --verbose: nbdkit: python[1]: debug: zero count=33554432 offset=0 may_trim=1 fua=0 nbdkit: python[1]: debug: zero count=33554432 offset=33554432 may_trim=1 fua=0 nbdkit: python[1]: error: /home/nsoffer/src/libguestfs/tmp/rhvupload.Au2B5I/rhv-upload-plugin.py: zero: error: Request-sent nbdkit: python[1]: debug: sending error reply: Input/output error qemu-img: error writing zeroes at offset 0: Input/output error Change all requests to read the whole response. Tested with imageio patch supporting keep alive connections: https://gerrit.ovirt.org/#/c/92296/ [1] https://docs.python.org/3.8/library/http.client.html#http.client.HTTPConnection.getresponse (cherry picked from commit f4e0a8342dbeb2c779c76e1807a37b24a0c96feb) --- v2v/rhv-upload-plugin.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py index 7c5084efd..2eec375f7 100644 --- a/v2v/rhv-upload-plugin.py +++ b/v2v/rhv-upload-plugin.py @@ -197,11 +197,13 @@ def get_options(h): http.endheaders() r = http.getresponse() + data = r.read() + if r.status == 200: # New imageio never needs authentication. h['needs_auth'] = False - j = json.loads(r.read()) + j = json.loads(data) h['can_zero'] = "zero" in j['features'] h['can_trim'] = "trim" in j['features'] h['can_flush'] = "flush" in j['features'] @@ -276,6 +278,7 @@ def pread(h, count, offset): request_failed(h, r, "could not read sector offset %d size %d" % (offset, count)) + return r.read() def pwrite(h, buf, offset): @@ -302,6 +305,8 @@ def pwrite(h, buf, offset): "could not write sector offset %d size %d" % (offset, count)) + r.read() + def zero(h, count, offset, may_trim): http = h['http'] transfer = h['transfer'] @@ -330,6 +335,8 @@ def zero(h, count, offset, may_trim): "could not zero sector offset %d size %d" % (offset, count)) + r.read() + def emulate_zero(h, count, offset): # qemu-img convert starts by trying to zero/trim the whole device. # Since we've just created a new disk it's safe to ignore these @@ -357,6 +364,8 @@ def emulate_zero(h, count, offset): "could not write zeroes offset %d size %d" % (offset, count)) + r.read() + def trim(h, count, offset): http = h['http'] transfer = h['transfer'] @@ -378,6 +387,8 @@ def trim(h, count, offset): "could not trim sector offset %d size %d" % (offset, count)) + r.read() + def flush(h): http = h['http'] transfer = h['transfer'] @@ -394,6 +405,8 @@ def flush(h): if r.status != 200: request_failed(h, r, "could not flush") + r.read() + def delete_disk_on_failure(h): disk_service = h['disk_service'] disk_service.remove() -- 2.17.2