[Libguestfs] [PATCH] v2v: -o rhv-upload: Support zero requests.

Richard W.M. Jones
Mon, 12 Mar 2018 13:11:30 -0000

---
 v2v/rhv-upload-plugin.py | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
index 4f5ed2ac5..9ccb393f8 100644
--- a/v2v/rhv-upload-plugin.py
+++ b/v2v/rhv-upload-plugin.py
@@ -156,7 +156,6 @@ def open(readonly):
         'disk': disk,
         'disk_service': disk_service,
         'failed': False,
-        'highestwrite': 0,
         'http': http,
         'path': destination_url.path,
         'transfer': transfer,
@@ -189,14 +188,10 @@ def pread(h, count, offset):
     return r.read()

 def pwrite(h, buf, offset):
+    http = h['http']
+    transfer=h['transfer']
+    transfer_service=h['transfer_service']
     count = len(buf)
-    h['highestwrite'] = max(h['highestwrite'], offset+count)
-    do_pwrite(h, buf, offset, count)
-
-def do_pwrite(h, buf, offset, count):
-    http = h['http']
-    transfer=h['transfer']
-    transfer_service=h['transfer_service']

     http.putrequest("PUT", h['path'])
     http.putheader("Authorization", transfer.signed_ticket)
@@ -214,19 +209,28 @@ def do_pwrite(h, buf, offset, count):
         raise RuntimeError("could not write sector (%d, %d): %d: %s"
%
                            (offset, count, r.status, r.reason))

-# 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
-# requests as long as they are smaller than the highest write seen.
-# After that we must emulate them with writes.
 def zero(h, count, offset, may_trim):
-    if offset+count < h['highestwrite']:
-        # count could be very large, so split into chunks.
-        while count > 0:
-            n = min(count, 65536)
-            buf = bytearray(n)
-            do_pwrite(h, buf, offset, n)
-            offset += n
-            count -= n
+    http = h['http']
+    transfer=h['transfer']
+    transfer_service=h['transfer_service']
+
+    # Construct the JSON request for zeroing.
+    buf = json.dumps({'op', "zero",
+                      'offset', offset,
+                      'size', count})
+
+    http.putrequest("POST", h['path'])
+    http.putheader("Authorization", transfer.signed_ticket)
+    http.putheader("Content-Length", len(buf))
+    http.endheaders()
+    http.send(buf)
+
+    r = http.getresponse()
+    if r.status != 200:
+        transfer_service.pause()
+        h['failed'] = True
+        raise RuntimeError("could not zero sector (%d, %d): %d: %s" %
+                           (offset, count, r.status, r.reason))

 def close(h):
     http = h['http']
--
2.13.2