]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
migration/channel: Centralize calling migration_channel_connect_outgoing
authorFabiano Rosas <farosas@suse.de>
Fri, 23 Jan 2026 14:16:55 +0000 (11:16 -0300)
committerFabiano Rosas <farosas@suse.de>
Fri, 23 Jan 2026 14:34:25 +0000 (11:34 -0300)
Make the synchronous calls evident by not hiding the call to
migration_channel_connect_outgoing() in the transport code. Have those
functions return and call the function at the upper level.

This helps with navigation: the transport code returns the ioc,
there's no need to look into them when browsing the code.

It also allows RDMA in the source side to use the same path as the
rest of the transports.

While here, document the async calls which are the exception.

Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Link: https://lore.kernel.org/qemu-devel/20260123141656.6765-26-farosas@suse.de
Signed-off-by: Fabiano Rosas <farosas@suse.de>
migration/channel.c
migration/exec.c
migration/exec.h
migration/fd.c
migration/fd.h
migration/file.c
migration/file.h
migration/rdma.c
migration/rdma.h

index 1e4778455d4a7050e3299ad00d61effd86525657..1e2935f926b4b6f16bb124d0d032629b0f2330c9 100644 (file)
 void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
                                 Error **errp)
 {
+    g_autoptr(QIOChannel) ioc = NULL;
+
     if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
         SocketAddress *saddr = &addr->u.socket;
         if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
             saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
             saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
             socket_connect_outgoing(s, saddr, errp);
+            /*
+             * async: after the socket is connected, calls
+             * migration_channel_connect_outgoing() directly.
+             */
+            return;
+
         } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
-            fd_connect_outgoing(s, saddr->u.fd.str, errp);
+            ioc = fd_connect_outgoing(s, saddr->u.fd.str, errp);
         }
 #ifdef CONFIG_RDMA
     } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
-        rdma_connect_outgoing(s, &addr->u.rdma, errp);
+        ioc = rdma_connect_outgoing(s, &addr->u.rdma, errp);
 #endif
     } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
-        exec_connect_outgoing(s, addr->u.exec.args, errp);
+        ioc = exec_connect_outgoing(s, addr->u.exec.args, errp);
     } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
-        file_connect_outgoing(s, &addr->u.file, errp);
+        ioc = file_connect_outgoing(s, &addr->u.file, errp);
     } else {
         error_setg(errp, "uri is not a valid migration protocol");
     }
+
+    if (ioc) {
+        migration_channel_connect_outgoing(s, ioc);
+    }
+
+    return;
 }
 
 void migration_connect_incoming(MigrationAddress *addr, Error **errp)
@@ -81,6 +95,12 @@ void migration_connect_incoming(MigrationAddress *addr, Error **errp)
     } else {
         error_setg(errp, "unknown migration protocol");
     }
+
+    /*
+     * async: the above routines all wait for the incoming connection
+     * and call back to migration_channel_process_incoming() to start
+     * the migration.
+     */
 }
 
 bool migration_has_main_and_multifd_channels(void)
index c3085e803e9094df418f84210f2b6dd190107465..a1a7ede3b4d86f85521e84eebbb7cf1a0d52814d 100644 (file)
@@ -40,7 +40,8 @@ const char *exec_get_cmd_path(void)
 }
 #endif
 
-void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)
+QIOChannel *exec_connect_outgoing(MigrationState *s, strList *command,
+                                  Error **errp)
 {
     QIOChannel *ioc = NULL;
     g_auto(GStrv) argv = strv_from_str_list(command);
@@ -50,12 +51,11 @@ void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)
     trace_migration_exec_outgoing(new_command);
     ioc = QIO_CHANNEL(qio_channel_command_new_spawn(args, O_RDWR, errp));
     if (!ioc) {
-        return;
+        return NULL;
     }
 
     qio_channel_set_name(ioc, "migration-exec-outgoing");
-    migration_channel_connect_outgoing(s, ioc);
-    object_unref(OBJECT(ioc));
+    return ioc;
 }
 
 static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
index e7e8e475ac7257f9f621fd7b84a7efadaa54df97..3e39270dce92df94bdc8ec75c282333a96c7261c 100644 (file)
 #ifndef QEMU_MIGRATION_EXEC_H
 #define QEMU_MIGRATION_EXEC_H
 
+#include "io/channel.h"
+
 #ifdef WIN32
 const char *exec_get_cmd_path(void);
 #endif
 void exec_connect_incoming(strList *host_port, Error **errp);
 
-void exec_connect_outgoing(MigrationState *s, strList *host_port, Error **errp);
+QIOChannel *exec_connect_outgoing(MigrationState *s, strList *host_port,
+                                  Error **errp);
 #endif
index 530aac1a5b1989958ee11dcf2594b1e2e1408395..f05f95992f8b6162d03c1d57045c8a976028a5df 100644 (file)
@@ -50,30 +50,31 @@ static bool migration_fd_valid(int fd)
     return false;
 }
 
-void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)
+QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,
+                                Error **errp)
 {
-    QIOChannel *ioc;
+    QIOChannel *ioc = NULL;
     int fd = monitor_get_fd(monitor_cur(), fdname, errp);
     if (fd == -1) {
-        return;
+        goto out;
     }
 
     if (!migration_fd_valid(fd)) {
         error_setg(errp, "fd: migration to a file is not supported."
                    " Use file: instead.");
-        return;
+        goto out;
     }
 
     trace_migration_fd_outgoing(fd);
     ioc = qio_channel_new_fd(fd, errp);
     if (!ioc) {
         close(fd);
-        return;
+        goto out;
     }
 
     qio_channel_set_name(ioc, "migration-fd-outgoing");
-    migration_channel_connect_outgoing(s, ioc);
-    object_unref(OBJECT(ioc));
+out:
+    return ioc;
 }
 
 static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
index 7211629270b07e655b84e4079608c65fd957cb8e..ce0b75127324822a2da64c350a2f80dc69a15f7b 100644 (file)
 
 #ifndef QEMU_MIGRATION_FD_H
 #define QEMU_MIGRATION_FD_H
+
+#include "io/channel.h"
+
 void fd_connect_incoming(const char *fdname, Error **errp);
 
-void fd_connect_outgoing(MigrationState *s, const char *fdname,
-                         Error **errp);
+QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,
+                                Error **errp);
 #endif
index b7b0fb519448f265fe46315e9b84862c8e067112..5618aced4947f6b128aa792251ab4a3fd034d5a0 100644 (file)
@@ -93,36 +93,38 @@ out:
     return ret;
 }
 
-void file_connect_outgoing(MigrationState *s,
-                           FileMigrationArgs *file_args, Error **errp)
+QIOChannel *file_connect_outgoing(MigrationState *s,
+                                  FileMigrationArgs *file_args, Error **errp)
 {
-    g_autoptr(QIOChannelFile) fioc = NULL;
+    QIOChannelFile *fioc = NULL;
     g_autofree char *filename = g_strdup(file_args->filename);
     uint64_t offset = file_args->offset;
-    QIOChannel *ioc;
+    QIOChannel *ioc = NULL;
 
     trace_migration_file_outgoing(filename);
 
     fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY, 0600, errp);
     if (!fioc) {
-        return;
+        goto out;
     }
 
     if (ftruncate(fioc->fd, offset)) {
         error_setg_errno(errp, errno,
                          "failed to truncate migration file to offset %" PRIx64,
                          offset);
-        return;
+        goto out;
     }
 
     outgoing_args.fname = g_strdup(filename);
 
     ioc = QIO_CHANNEL(fioc);
     if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
-        return;
+        ioc = NULL;
+        goto out;
     }
     qio_channel_set_name(ioc, "migration-file-outgoing");
-    migration_channel_connect_outgoing(s, ioc);
+out:
+    return ioc;
 }
 
 static gboolean file_accept_incoming_migration(QIOChannel *ioc,
index 9b1e874bb7e8e2df4bb0bffd0dc833aeabe1c568..5936c64fea2ef48d30d7802c8c01da3a4a89edff 100644 (file)
@@ -9,14 +9,15 @@
 #define QEMU_MIGRATION_FILE_H
 
 #include "qapi/qapi-types-migration.h"
+#include "io/channel.h"
 #include "io/task.h"
 #include "channel.h"
 #include "multifd.h"
 
 void file_connect_incoming(FileMigrationArgs *file_args, Error **errp);
 
-void file_connect_outgoing(MigrationState *s,
-                           FileMigrationArgs *file_args, Error **errp);
+QIOChannel *file_connect_outgoing(MigrationState *s,
+                                  FileMigrationArgs *file_args, Error **errp);
 int file_parse_offset(char *filespec, uint64_t *offsetp, Error **errp);
 void file_cleanup_outgoing_migration(void);
 bool file_send_channel_create(gpointer opaque, Error **errp);
index e628a20aecc176b9ee799607b4d55ca4f942690c..55ab85650a2d416f48cf70227461f220de9fdfa5 100644 (file)
@@ -3933,8 +3933,8 @@ err:
     g_free(rdma);
 }
 
-void rdma_connect_outgoing(void *opaque,
-                           InetSocketAddress *host_port, Error **errp)
+QIOChannel *rdma_connect_outgoing(void *opaque,
+                                  InetSocketAddress *host_port, Error **errp)
 {
     MigrationState *s = opaque;
     RDMAContext *rdma_return_path = NULL;
@@ -3944,7 +3944,7 @@ void rdma_connect_outgoing(void *opaque,
     /* Avoid ram_block_discard_disable(), cannot change during migration. */
     if (ram_block_discard_is_required()) {
         error_setg(errp, "RDMA: cannot disable RAM discard");
-        return;
+        return NULL;
     }
 
     rdma = qemu_rdma_data_init(host_port, errp);
@@ -3994,12 +3994,11 @@ void rdma_connect_outgoing(void *opaque,
     trace_rdma_connect_outgoing_after_rdma_connect();
 
     s->rdma_migration = true;
-    migration_outgoing_setup(rdma_new_output(rdma));
-    migration_start_outgoing(s);
-    return;
+    return rdma_new_output(rdma);
 return_path_err:
     qemu_rdma_cleanup(rdma);
 err:
     g_free(rdma);
     g_free(rdma_return_path);
+    return NULL;
 }
index 170c25cf44aaad55039628429ec6fed33dc939c9..8a6515f13006608cc36274378f0a831a57d355ca 100644 (file)
@@ -21,8 +21,8 @@
 
 #include "system/memory.h"
 
-void rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,
-                           Error **errp);
+QIOChannel *rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,
+                                  Error **errp);
 
 void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp);