Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2177620/?format=api
{ "id": 2177620, "url": "http://patchwork.ozlabs.org/api/patches/2177620/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20251226211930.27565-20-farosas@suse.de/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20251226211930.27565-20-farosas@suse.de>", "list_archive_url": null, "date": "2025-12-26T21:19:21", "name": "[RFC,19/25] migration/channel: Make synchronous calls evident", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "764c28716a4dcf1397c9d8dea1722598973fc34c", "submitter": { "id": 85343, "url": "http://patchwork.ozlabs.org/api/people/85343/?format=api", "name": "Fabiano Rosas", "email": "farosas@suse.de" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20251226211930.27565-20-farosas@suse.de/mbox/", "series": [ { "id": 486505, "url": "http://patchwork.ozlabs.org/api/series/486505/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=486505", "date": "2025-12-26T21:19:04", "name": "migration: Cleanup early connection code", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/486505/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2177620/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2177620/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256\n header.s=susede2_rsa header.b=Rp9O1F40;\n\tdkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=4BLrPMqc;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.a=rsa-sha256 header.s=susede2_rsa header.b=Rp9O1F40;\n\tdkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=4BLrPMqc;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)", "smtp-out1.suse.de;\n\tnone" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4ddJTq1WFlz1y3s\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 27 Dec 2025 08:22:07 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vZFEU-0001Sf-Qw; Fri, 26 Dec 2025 16:20:23 -0500", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <farosas@suse.de>) id 1vZFEO-0001RU-SP\n for qemu-devel@nongnu.org; Fri, 26 Dec 2025 16:20:18 -0500", "from smtp-out1.suse.de ([195.135.223.130])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <farosas@suse.de>) id 1vZFEL-00047E-P0\n for qemu-devel@nongnu.org; Fri, 26 Dec 2025 16:20:16 -0500", "from imap1.dmz-prg2.suse.org (unknown [10.150.64.97])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-out1.suse.de (Postfix) with ESMTPS id 583163368B;\n Fri, 26 Dec 2025 21:20:06 +0000 (UTC)", "from imap1.dmz-prg2.suse.org (localhost [127.0.0.1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 067583EA63;\n Fri, 26 Dec 2025 21:20:04 +0000 (UTC)", "from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167])\n by imap1.dmz-prg2.suse.org with ESMTPSA id 6Lv3LAT8TmnwJwAAD6G6ig\n (envelope-from <farosas@suse.de>); Fri, 26 Dec 2025 21:20:04 +0000" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1766784006;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=+i/DLae2OO2ZVdC7i6O7sLm4eKDHTytV8OmukLC/6es=;\n b=Rp9O1F40umf/taLwpX775TNvuXgfQhKViJODeCyZWL6VVDzmbImfUtlj0Bu3VeEqZnETY1\n gLnn6u/aBfFtUB0vnumytSl1ayyC5Npag/p93A1GGXQGc71HnUBH49BOnF+UqfluZRbLIW\n wz0aMgtVIhmqmGCCQvVKqc0R31UCqBQ=", "v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1766784006;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=+i/DLae2OO2ZVdC7i6O7sLm4eKDHTytV8OmukLC/6es=;\n b=4BLrPMqcJDGlxK8hu9e0ypCvORqSKdz/bfZ7FTAEsPwa549qAET7QXtKATi2M3VyrZHBX9\n lpALMmtEIrmWUHCw==", "v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1766784006;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=+i/DLae2OO2ZVdC7i6O7sLm4eKDHTytV8OmukLC/6es=;\n b=Rp9O1F40umf/taLwpX775TNvuXgfQhKViJODeCyZWL6VVDzmbImfUtlj0Bu3VeEqZnETY1\n gLnn6u/aBfFtUB0vnumytSl1ayyC5Npag/p93A1GGXQGc71HnUBH49BOnF+UqfluZRbLIW\n wz0aMgtVIhmqmGCCQvVKqc0R31UCqBQ=", "v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1766784006;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=+i/DLae2OO2ZVdC7i6O7sLm4eKDHTytV8OmukLC/6es=;\n b=4BLrPMqcJDGlxK8hu9e0ypCvORqSKdz/bfZ7FTAEsPwa549qAET7QXtKATi2M3VyrZHBX9\n lpALMmtEIrmWUHCw==" ], "From": "Fabiano Rosas <farosas@suse.de>", "To": "qemu-devel@nongnu.org", "Cc": "peterx@redhat.com,\n\tLi Zhijian <lizhijian@fujitsu.com>", "Subject": "[RFC PATCH 19/25] migration/channel: Make synchronous calls evident", "Date": "Fri, 26 Dec 2025 18:19:21 -0300", "Message-ID": "<20251226211930.27565-20-farosas@suse.de>", "X-Mailer": "git-send-email 2.51.0", "In-Reply-To": "<20251226211930.27565-1-farosas@suse.de>", "References": "<20251226211930.27565-1-farosas@suse.de>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Spam-Score": "-2.80", "X-Spamd-Result": "default: False [-2.80 / 50.00]; BAYES_HAM(-3.00)[100.00%];\n MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000];\n R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.20)[-0.988];\n MIME_GOOD(-0.10)[text/plain]; RCVD_VIA_SMTP_AUTH(0.00)[];\n MIME_TRACE(0.00)[0:+]; FUZZY_RATELIMITED(0.00)[rspamd.com];\n TO_DN_SOME(0.00)[]; ARC_NA(0.00)[];\n DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519];\n URIBL_BLOCKED(0.00)[suse.de:email,suse.de:mid,imap1.dmz-prg2.suse.org:helo];\n FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[];\n RCPT_COUNT_THREE(0.00)[3]; RCVD_COUNT_TWO(0.00)[2];\n TO_MATCH_ENVRCPT_ALL(0.00)[];\n DBL_BLOCKED_OPENRESOLVER(0.00)[suse.de:email,suse.de:mid,imap1.dmz-prg2.suse.org:helo];\n RCVD_TLS_ALL(0.00)[]", "Received-SPF": "pass client-ip=195.135.223.130; envelope-from=farosas@suse.de;\n helo=smtp-out1.suse.de", "X-Spam_score_int": "-43", "X-Spam_score": "-4.4", "X-Spam_bar": "----", "X-Spam_report": "(-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Make the synchronous calls evident by not hiding the call to\nmigration_channel_connect_outgoing in the transport code. Have those\nfunctions return and call the migration_connect_outgoing() at the\nupper level.\n\nThis helps with navigation: the transport code returns the ioc,\nthere's no need to look into them when browsing the code.\n\nIt also allows RDMA in the source side to use the same path as the\nrest of the transports.\n\nWhile here, document the async calls which are the exception.\n\nSigned-off-by: Fabiano Rosas <farosas@suse.de>\n---\n migration/channel.c | 30 +++++++++++++++++++++++++-----\n migration/channel.h | 2 +-\n migration/exec.c | 8 ++++----\n migration/exec.h | 5 ++++-\n migration/fd.c | 13 +++++++------\n migration/fd.h | 7 +++++--\n migration/file.c | 18 ++++++++++--------\n migration/file.h | 5 +++--\n migration/migration.c | 3 +--\n migration/rdma.c | 11 +++++------\n migration/rdma.h | 4 ++--\n 11 files changed, 67 insertions(+), 39 deletions(-)", "diff": "diff --git a/migration/channel.c b/migration/channel.c\nindex a06aa8189c..205f8a26d1 100644\n--- a/migration/channel.c\n+++ b/migration/channel.c\n@@ -31,29 +31,43 @@\n #include \"trace.h\"\n #include \"yank_functions.h\"\n \n-void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,\n+bool migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,\n Error **errp)\n {\n+ g_autoptr(QIOChannel) ioc = NULL;\n+\n if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {\n SocketAddress *saddr = &addr->u.socket;\n if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||\n saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||\n saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {\n socket_connect_outgoing(s, saddr, errp);\n+ /*\n+ * async: after the socket is connected, calls\n+ * migration_channel_connect_outgoing() directly.\n+ */\n+ return true;\n } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {\n- fd_connect_outgoing(s, saddr->u.fd.str, errp);\n+ ioc = fd_connect_outgoing(s, saddr->u.fd.str, errp);\n }\n #ifdef CONFIG_RDMA\n } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {\n- rdma_connect_outgoing(s, &addr->u.rdma, errp);\n+ ioc = rdma_connect_outgoing(s, &addr->u.rdma, errp);\n #endif\n } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {\n- exec_connect_outgoing(s, addr->u.exec.args, errp);\n+ ioc = exec_connect_outgoing(s, addr->u.exec.args, errp);\n } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {\n- file_connect_outgoing(s, &addr->u.file, errp);\n+ ioc = file_connect_outgoing(s, &addr->u.file, errp);\n } else {\n error_setg(errp, \"uri is not a valid migration protocol\");\n }\n+\n+ if (!ioc) {\n+ return false;\n+ }\n+\n+ migration_channel_connect_outgoing(s, ioc);\n+ return true;\n }\n \n void migration_connect_incoming(MigrationAddress *addr, Error **errp)\n@@ -78,6 +92,12 @@ void migration_connect_incoming(MigrationAddress *addr, Error **errp)\n } else {\n error_setg(errp, \"unknown migration protocol\");\n }\n+\n+ /*\n+ * async: the above routines all wait for the incoming connection\n+ * and call back to migration_channel_process_incoming() to start\n+ * the migration.\n+ */\n }\n \n bool migration_has_main_and_multifd_channels(void)\ndiff --git a/migration/channel.h b/migration/channel.h\nindex 727eabf16c..4851179ae6 100644\n--- a/migration/channel.h\n+++ b/migration/channel.h\n@@ -39,7 +39,7 @@ int migration_channel_read_peek(QIOChannel *ioc,\n bool migration_has_main_and_multifd_channels(void);\n bool migration_has_all_channels(void);\n \n-void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,\n+bool migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,\n Error **errp);\n void migration_connect_incoming(MigrationAddress *addr, Error **errp);\n #endif\ndiff --git a/migration/exec.c b/migration/exec.c\nindex c3085e803e..a1a7ede3b4 100644\n--- a/migration/exec.c\n+++ b/migration/exec.c\n@@ -40,7 +40,8 @@ const char *exec_get_cmd_path(void)\n }\n #endif\n \n-void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)\n+QIOChannel *exec_connect_outgoing(MigrationState *s, strList *command,\n+ Error **errp)\n {\n QIOChannel *ioc = NULL;\n g_auto(GStrv) argv = strv_from_str_list(command);\n@@ -50,12 +51,11 @@ void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)\n trace_migration_exec_outgoing(new_command);\n ioc = QIO_CHANNEL(qio_channel_command_new_spawn(args, O_RDWR, errp));\n if (!ioc) {\n- return;\n+ return NULL;\n }\n \n qio_channel_set_name(ioc, \"migration-exec-outgoing\");\n- migration_channel_connect_outgoing(s, ioc);\n- object_unref(OBJECT(ioc));\n+ return ioc;\n }\n \n static gboolean exec_accept_incoming_migration(QIOChannel *ioc,\ndiff --git a/migration/exec.h b/migration/exec.h\nindex e7e8e475ac..3e39270dce 100644\n--- a/migration/exec.h\n+++ b/migration/exec.h\n@@ -20,10 +20,13 @@\n #ifndef QEMU_MIGRATION_EXEC_H\n #define QEMU_MIGRATION_EXEC_H\n \n+#include \"io/channel.h\"\n+\n #ifdef WIN32\n const char *exec_get_cmd_path(void);\n #endif\n void exec_connect_incoming(strList *host_port, Error **errp);\n \n-void exec_connect_outgoing(MigrationState *s, strList *host_port, Error **errp);\n+QIOChannel *exec_connect_outgoing(MigrationState *s, strList *host_port,\n+ Error **errp);\n #endif\ndiff --git a/migration/fd.c b/migration/fd.c\nindex b689426ad4..bbf380d1a0 100644\n--- a/migration/fd.c\n+++ b/migration/fd.c\n@@ -49,12 +49,13 @@ static bool migration_fd_valid(int fd)\n return false;\n }\n \n-void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)\n+QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,\n+ Error **errp)\n {\n- QIOChannel *ioc;\n+ QIOChannel *ioc = NULL;\n int fd = monitor_get_fd(monitor_cur(), fdname, errp);\n if (fd == -1) {\n- return;\n+ goto out;\n }\n \n if (!migration_fd_valid(fd)) {\n@@ -66,12 +67,12 @@ void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)\n ioc = qio_channel_new_fd(fd, errp);\n if (!ioc) {\n close(fd);\n- return;\n+ goto out;\n }\n \n qio_channel_set_name(ioc, \"migration-fd-outgoing\");\n- migration_channel_connect_outgoing(s, ioc);\n- object_unref(OBJECT(ioc));\n+out:\n+ return ioc;\n }\n \n static gboolean fd_accept_incoming_migration(QIOChannel *ioc,\ndiff --git a/migration/fd.h b/migration/fd.h\nindex 7211629270..ce0b751273 100644\n--- a/migration/fd.h\n+++ b/migration/fd.h\n@@ -16,8 +16,11 @@\n \n #ifndef QEMU_MIGRATION_FD_H\n #define QEMU_MIGRATION_FD_H\n+\n+#include \"io/channel.h\"\n+\n void fd_connect_incoming(const char *fdname, Error **errp);\n \n-void fd_connect_outgoing(MigrationState *s, const char *fdname,\n- Error **errp);\n+QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,\n+ Error **errp);\n #endif\ndiff --git a/migration/file.c b/migration/file.c\nindex b7b0fb5194..5618aced49 100644\n--- a/migration/file.c\n+++ b/migration/file.c\n@@ -93,36 +93,38 @@ out:\n return ret;\n }\n \n-void file_connect_outgoing(MigrationState *s,\n- FileMigrationArgs *file_args, Error **errp)\n+QIOChannel *file_connect_outgoing(MigrationState *s,\n+ FileMigrationArgs *file_args, Error **errp)\n {\n- g_autoptr(QIOChannelFile) fioc = NULL;\n+ QIOChannelFile *fioc = NULL;\n g_autofree char *filename = g_strdup(file_args->filename);\n uint64_t offset = file_args->offset;\n- QIOChannel *ioc;\n+ QIOChannel *ioc = NULL;\n \n trace_migration_file_outgoing(filename);\n \n fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY, 0600, errp);\n if (!fioc) {\n- return;\n+ goto out;\n }\n \n if (ftruncate(fioc->fd, offset)) {\n error_setg_errno(errp, errno,\n \"failed to truncate migration file to offset %\" PRIx64,\n offset);\n- return;\n+ goto out;\n }\n \n outgoing_args.fname = g_strdup(filename);\n \n ioc = QIO_CHANNEL(fioc);\n if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {\n- return;\n+ ioc = NULL;\n+ goto out;\n }\n qio_channel_set_name(ioc, \"migration-file-outgoing\");\n- migration_channel_connect_outgoing(s, ioc);\n+out:\n+ return ioc;\n }\n \n static gboolean file_accept_incoming_migration(QIOChannel *ioc,\ndiff --git a/migration/file.h b/migration/file.h\nindex 9b1e874bb7..5936c64fea 100644\n--- a/migration/file.h\n+++ b/migration/file.h\n@@ -9,14 +9,15 @@\n #define QEMU_MIGRATION_FILE_H\n \n #include \"qapi/qapi-types-migration.h\"\n+#include \"io/channel.h\"\n #include \"io/task.h\"\n #include \"channel.h\"\n #include \"multifd.h\"\n \n void file_connect_incoming(FileMigrationArgs *file_args, Error **errp);\n \n-void file_connect_outgoing(MigrationState *s,\n- FileMigrationArgs *file_args, Error **errp);\n+QIOChannel *file_connect_outgoing(MigrationState *s,\n+ FileMigrationArgs *file_args, Error **errp);\n int file_parse_offset(char *filespec, uint64_t *offsetp, Error **errp);\n void file_cleanup_outgoing_migration(void);\n bool file_send_channel_create(gpointer opaque, Error **errp);\ndiff --git a/migration/migration.c b/migration/migration.c\nindex 9e69141e86..c75c2c7e52 100644\n--- a/migration/migration.c\n+++ b/migration/migration.c\n@@ -2217,9 +2217,8 @@ out:\n static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)\n {\n MigrationState *s = migrate_get_current();\n- Error *local_err = NULL;\n \n- migration_connect_outgoing(s, addr, &local_err);\n+ migration_connect_outgoing(s, addr, errp);\n }\n \n void qmp_migrate_cancel(Error **errp)\ndiff --git a/migration/rdma.c b/migration/rdma.c\nindex 6e9ca5f5f6..3db3a89bdb 100644\n--- a/migration/rdma.c\n+++ b/migration/rdma.c\n@@ -3923,8 +3923,8 @@ err:\n g_free(rdma);\n }\n \n-void rdma_connect_outgoing(void *opaque,\n- InetSocketAddress *host_port, Error **errp)\n+QIOChannel *rdma_connect_outgoing(void *opaque,\n+ InetSocketAddress *host_port, Error **errp)\n {\n MigrationState *s = opaque;\n RDMAContext *rdma_return_path = NULL;\n@@ -3934,7 +3934,7 @@ void rdma_connect_outgoing(void *opaque,\n /* Avoid ram_block_discard_disable(), cannot change during migration. */\n if (ram_block_discard_is_required()) {\n error_setg(errp, \"RDMA: cannot disable RAM discard\");\n- return;\n+ return NULL;\n }\n \n rdma = qemu_rdma_data_init(host_port, errp);\n@@ -3984,12 +3984,11 @@ void rdma_connect_outgoing(void *opaque,\n trace_rdma_connect_outgoing_after_rdma_connect();\n \n s->rdma_migration = true;\n- migration_outgoing_setup(rdma_new_ioc(rdma));\n- migration_start_outgoing(s);\n- return;\n+ return rdma_new_ioc(rdma);\n return_path_err:\n qemu_rdma_cleanup(rdma);\n err:\n g_free(rdma);\n g_free(rdma_return_path);\n+ return NULL;\n }\ndiff --git a/migration/rdma.h b/migration/rdma.h\nindex 170c25cf44..8a6515f130 100644\n--- a/migration/rdma.h\n+++ b/migration/rdma.h\n@@ -21,8 +21,8 @@\n \n #include \"system/memory.h\"\n \n-void rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,\n- Error **errp);\n+QIOChannel *rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,\n+ Error **errp);\n \n void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp);\n \n", "prefixes": [ "RFC", "19/25" ] }