From 320ba554d11f75c4c2753968505a1d3308b64dda Mon Sep 17 00:00:00 2001
From: Nir Soffer <nirsof@gmail.com>
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