Blame SOURCES/0025-v2v-rvh-upload-plugin-Always-read-the-response.patch

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