The oVirt server may fail a PUT request before reading all request body.
However before closing the connection, it writes a detailed error
response, that will make debugging issues like expired tickets much
easier to handle. If we don't get the response and log the error, the
error may be lost when the daemon log is rotated.
Change pwrite() and emulate_zero() to get the response after EPIPE,
failing with the error response from the oVirt server.
Here is an example error log when a ticket expires during import:
nbdkit: python[1]: error:
/home/nsoffer/src/libguestfs/tmp/v2v.pRoyXm/rhv-upload-plugin.py:
pwrite: error: ('%s: %d %s: %r', 'could not write sector offset 1841154048
size 1024', 403,
'Forbidden', b'{"explanation": "Access was denied to this
resource.", "code": 403, "detail":
"Ticket u\'6071e16f-ec60-4ff9-a594-10b0faae3617\' expired",
"title": "Forbidden"}')
---
v2v/rhv-upload-plugin.py | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
index 2d686c2da..7327ea4c5 100644
--- a/v2v/rhv-upload-plugin.py
+++ b/v2v/rhv-upload-plugin.py
@@ -17,6 +17,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import builtins
+import errno
import json
import logging
import socket
@@ -357,7 +358,12 @@ def pwrite(h, buf, offset):
http.putheader("Content-Range", "bytes %d-%d/*" % (offset,
offset+count-1))
http.putheader("Content-Length", str(count))
http.endheaders()
- http.send(buf)
+
+ try:
+ http.send(buf)
+ except socket.error as e:
+ if e[0] != errno.EPIPE:
+ raise
r = http.getresponse()
if r.status != 200:
@@ -413,11 +419,15 @@ def emulate_zero(h, count, offset):
http.putheader("Content-Length", str(count))
http.endheaders()
- buf = bytearray(128*1024)
- while count > len(buf):
- http.send(buf)
- count -= len(buf)
- http.send(buffer(buf, 0, count))
+ try:
+ buf = bytearray(128*1024)
+ while count > len(buf):
+ http.send(buf)
+ count -= len(buf)
+ http.send(buffer(buf, 0, count))
+ except socket.error as e:
+ if e[0] != errno.EPIPE:
+ raise
r = http.getresponse()
if r.status != 200:
--
2.17.1