Blame SOURCES/0030-v2v-rhv-upload-plugin-Defer-imageio-connection.patch

7ed5e3
From 987ddcd2ad7546212d3afed52b56f27a664624d6 Mon Sep 17 00:00:00 2001
7ed5e3
From: Nir Soffer <nsoffer@redhat.com>
7ed5e3
Date: Thu, 21 Jan 2021 03:40:00 +0200
7ed5e3
Subject: [PATCH] v2v: rhv-upload-plugin: Defer imageio connection
7ed5e3
7ed5e3
When using vddk input with certain vmware version, qemu-img may spend
7ed5e3
lot of time getting source image extents. If getting image extents takes
7ed5e3
more than 60 seconds, imageio server closes the idle connection, and the
7ed5e3
transfer will fail on the first write with:
7ed5e3
7ed5e3
nbdkit: python[1]: error: /var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py: pwrite: error:
7ed5e3
Traceback (most recent call last):
7ed5e3
   File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 94, in wrapper
7ed5e3
    return func(h, *args)
7ed5e3
   File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 230, in pwrite
7ed5e3
    r = http.getresponse()
7ed5e3
   File "/usr/lib64/python3.6/http/client.py", line 1361, in getresponse
7ed5e3
    response.begin()
7ed5e3
   File "/usr/lib64/python3.6/http/client.py", line 311, in begin
7ed5e3
    version, status, reason = self._read_status()
7ed5e3
   File "/usr/lib64/python3.6/http/client.py", line 280, in _read_status
7ed5e3
    raise RemoteDisconnected("Remote end closed connection without"
7ed5e3
 http.client.RemoteDisconnected: Remote end closed connection without response
7ed5e3
7ed5e3
This happens only when not using unix socket, for example when running
7ed5e3
on non-ovirt host, or ovirt host from another data center, or when using
7ed5e3
-oo rhv_direct=false
7ed5e3
7ed5e3
When using unix socket, we close the initial HTTPSConnection, and
7ed5e3
created a new UnixHTTPConnection. This connection is not connected to
7ed5e3
the server yet. When qemu-img tries to access the server, the connection
7ed5e3
is connected automatically.
7ed5e3
7ed5e3
Fix the issue by closing the initial connection used to get server
7ed5e3
options and initialize the handle, and storing a closed connection in
7ed5e3
the handle.
7ed5e3
7ed5e3
Here is the flow with this change:
7ed5e3
7ed5e3
1. Create HTTPSConnection for getting server options
7ed5e3
2. Close the connection[1]
7ed5e3
3. If using unix socket, create UnixHTTPConnection.
7ed5e3
4. Store the connection in the handle.
7ed5e3
5. When qemu-img try to write/zero, the connection is reconnects
7ed5e3
   automatically to imageio server[2]
7ed5e3
7ed5e3
Tested by adding a 300 milliseconds delay in nbdkit file plugin. Due to
7ed5e3
the way qemu-img works, this cause more than 2 minutes delay after
7ed5e3
open() but before the first pwrite(). Without this change, the import
7ed5e3
fails consistently when using rhv_direct=false.
7ed5e3
7ed5e3
[1] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L958
7ed5e3
[2] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L972
7ed5e3
7ed5e3
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
7ed5e3
(cherry picked from commit 1d5fc257765c444644e5bfc6525e86ff201755f0)
7ed5e3
---
7ed5e3
 v2v/rhv-upload-plugin.py | 9 +++++++++
7ed5e3
 1 file changed, 9 insertions(+)
7ed5e3
7ed5e3
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
7ed5e3
index 471102da..7cd6dea6 100644
7ed5e3
--- a/v2v/rhv-upload-plugin.py
7ed5e3
+++ b/v2v/rhv-upload-plugin.py
7ed5e3
@@ -117,6 +117,15 @@ def open(readonly):
7ed5e3
         destination_url = parse_transfer_url(transfer)
7ed5e3
         http = create_http(destination_url)
7ed5e3
         options = get_options(http, destination_url)
7ed5e3
+
7ed5e3
+        # Close the initial connection to imageio server. When qemu-img will
7ed5e3
+        # try to access the server, HTTPConnection will reconnect
7ed5e3
+        # automatically. If we keep this connection idle and qemu-img is too
7ed5e3
+        # slow getting image extents, imageio server may close the connection,
7ed5e3
+        # and the import will fail on the first write.
7ed5e3
+        # See https://bugzilla.redhat.com/1916176.
7ed5e3
+        http.close()
7ed5e3
+
7ed5e3
         http = optimize_http(http, host, options)
7ed5e3
     except:
7ed5e3
         cancel_transfer(connection, transfer)
7ed5e3
-- 
7ed5e3
2.18.4
7ed5e3