From: "Maciej S. Szmigiero" <maciej.szmigi...@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.szmigi...@oracle.com> --- migration/multifd.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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);