diff mbox series

[v4,08/33] migration/multifd: Allow premature EOF on TLS incoming channels

Message ID baf944c37ead5d30d7e268b2a4074d9acaac2db0.1738171076.git.maciej.szmigiero@oracle.com (mailing list archive)
State New
Headers show
Series Multifd ���� device state transfer support with VFIO consumer | expand

Commit Message

Maciej S. Szmigiero Jan. 30, 2025, 10:08 a.m. UTC
From: "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>

Multifd send channels are terminated by calling
qio_channel_shutdown(QIO_CHANNEL_SHUTDOWN_BOTH) in
multifd_send_terminate_threads(), which in the TLS case essentially
calls shutdown(SHUT_RDWR) on the underlying raw socket.

Unfortunately, this does not terminate the TLS session properly and
the receive side sees this as a GNUTLS_E_PREMATURE_TERMINATION error.

The only reason why this wasn't causing migration failures is because
the current migration code apparently does not check for migration
error being set after the end of the multifd receive process.

However, this will change soon so the multifd receive code has to be
prepared to not return an error on such premature TLS session EOF.
Use the newly introduced QIOChannelTLS method for that.

It's worth noting that even if the sender were to be changed to terminate
the TLS connection properly the receive side still needs to remain
compatible with older QEMU bit stream which does not do this.

Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
---
 migration/multifd.c | 8 ++++++++
 1 file changed, 8 insertions(+)
diff mbox series

Patch

diff --git a/migration/multifd.c b/migration/multifd.c
index ab73d6d984cf..ceaad930e141 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1310,6 +1310,7 @@  void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
     Error *local_err = NULL;
     bool use_packets = multifd_use_packets();
     int id;
+    QIOChannelTLS *ioc_tls;
 
     if (use_packets) {
         id = multifd_recv_initial_packet(ioc, &local_err);
@@ -1337,6 +1338,13 @@  void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
     p->c = ioc;
     object_ref(OBJECT(ioc));
 
+    ioc_tls = QIO_CHANNEL_TLS(object_dynamic_cast(OBJECT(ioc),
+                                                  TYPE_QIO_CHANNEL_TLS));
+    if (ioc_tls) {
+        /* Multifd send channels do not terminate the TLS session properly */
+        qio_channel_tls_set_premature_eof_okay(ioc_tls, true);
+    }
+
     p->thread_created = true;
     qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p,
                        QEMU_THREAD_JOINABLE);