From: Fabiano Rosas <farosas@suse.de>
To: Peter Xu <peterx@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [RFC PATCH 24/25] migration: Move URI parsing to channel.c
Date: Mon, 29 Dec 2025 18:22:04 -0300 [thread overview]
Message-ID: <87344t7zlv.fsf@suse.de> (raw)
In-Reply-To: <aVLtyglUqAkT4VEI@x1.local>
Peter Xu <peterx@redhat.com> writes:
> On Fri, Dec 26, 2025 at 06:19:26PM -0300, Fabiano Rosas wrote:
>> The migrate_uri_parse function is responsible for converting the URI
>> string into a MigrationChannel for consumption by the rest of the
>> code. Move it to channel.c and add a wrapper that calls both URI and
>> channels parsing.
>>
>> While here, add some words about the memory management of the
>> MigrationChannel object, which is slightly different from
>> migrate_uri_parse() and migrate_channels_parse(). The former takes a
>> string and has to allocate a MigrationChannel, the latter takes a QAPI
>> object that is managed by the QAPI code.
>>
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>
> There're some comments added into migration_connect(), that I still don't
> think I fully agree upon.. but the rest looks all good to me.
>
You're talking about the comments not being at the right place? I can
duplicate them in migration_connect_outgoing|incoming.
> That's probably to be discussed separately anyway, I think you can take
> mine here:
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
>
>> ---
>> migration/channel.c | 97 +++++++++++++++++++++++++++++++++++++++++--
>> migration/channel.h | 9 ++--
>> migration/migration.c | 95 ++----------------------------------------
>> 3 files changed, 101 insertions(+), 100 deletions(-)
>>
>> diff --git a/migration/channel.c b/migration/channel.c
>> index 8b43c3d983..d30e29c9b3 100644
>> --- a/migration/channel.c
>> +++ b/migration/channel.c
>> @@ -40,6 +40,12 @@ bool migration_connect(MigrationAddress *addr, bool out, Error **errp)
>> SocketAddress *saddr;
>> ERRP_GUARD();
>>
>> + /*
>> + * This is reached from a QMP command, the transport code below
>> + * must copy the relevant parts of 'addr' before this function
>> + * returns because the QAPI code will free it.
>> + */
>> +
>> switch (addr->transport) {
>> case MIGRATION_ADDRESS_TYPE_SOCKET:
>> saddr = &addr->u.socket;
>> @@ -318,10 +324,10 @@ int migration_channel_read_peek(QIOChannel *ioc,
>> return 0;
>> }
>>
>> -bool migrate_channels_parse(MigrationChannelList *channels,
>> - MigrationChannel **main_channelp,
>> - MigrationChannel **cpr_channelp,
>> - Error **errp)
>> +static bool migrate_channels_parse(MigrationChannelList *channels,
>> + MigrationChannel **main_channelp,
>> + MigrationChannel **cpr_channelp,
>> + Error **errp)
>> {
>> MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
>> bool single_channel;
>> @@ -353,6 +359,15 @@ bool migrate_channels_parse(MigrationChannelList *channels,
>> }
>> }
>>
>> + /*
>> + * These don't technically need to be cloned because they come
>> + * from a QAPI object ('channels'). The top-level caller
>> + * (qmp_migrate) needs to copy the necessary information before
>> + * returning from the QMP command. Cloning here is just to keep
>> + * the interface consistent with migrate_uri_parse() that _does
>> + * not_ take a QAPI object and instead allocates and transfers
>> + * ownership of a MigrationChannel to qmp_migrate.
>> + */
>> if (cpr_channelp) {
>> *cpr_channelp = QAPI_CLONE(MigrationChannel,
>> channelv[MIGRATION_CHANNEL_TYPE_CPR]);
>> @@ -368,3 +383,77 @@ bool migrate_channels_parse(MigrationChannelList *channels,
>>
>> return true;
>> }
>> +
>> +bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
>> + Error **errp)
>> +{
>> + g_autoptr(MigrationChannel) val = g_new0(MigrationChannel, 1);
>> + g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1);
>> + InetSocketAddress *isock = &addr->u.rdma;
>> + strList **tail = &addr->u.exec.args;
>> +
>> + if (strstart(uri, "exec:", NULL)) {
>> + addr->transport = MIGRATION_ADDRESS_TYPE_EXEC;
>> +#ifdef WIN32
>> + QAPI_LIST_APPEND(tail, g_strdup(exec_get_cmd_path()));
>> + QAPI_LIST_APPEND(tail, g_strdup("/c"));
>> +#else
>> + QAPI_LIST_APPEND(tail, g_strdup("/bin/sh"));
>> + QAPI_LIST_APPEND(tail, g_strdup("-c"));
>> +#endif
>> + QAPI_LIST_APPEND(tail, g_strdup(uri + strlen("exec:")));
>> + } else if (strstart(uri, "rdma:", NULL)) {
>> + if (inet_parse(isock, uri + strlen("rdma:"), errp)) {
>> + qapi_free_InetSocketAddress(isock);
>> + return false;
>> + }
>> + addr->transport = MIGRATION_ADDRESS_TYPE_RDMA;
>> + } else if (strstart(uri, "tcp:", NULL) ||
>> + strstart(uri, "unix:", NULL) ||
>> + strstart(uri, "vsock:", NULL) ||
>> + strstart(uri, "fd:", NULL)) {
>> + addr->transport = MIGRATION_ADDRESS_TYPE_SOCKET;
>> + SocketAddress *saddr = socket_parse(uri, errp);
>> + if (!saddr) {
>> + return false;
>> + }
>> + addr->u.socket.type = saddr->type;
>> + addr->u.socket.u = saddr->u;
>> + /* Don't free the objects inside; their ownership moved to "addr" */
>> + g_free(saddr);
>> + } else if (strstart(uri, "file:", NULL)) {
>> + addr->transport = MIGRATION_ADDRESS_TYPE_FILE;
>> + addr->u.file.filename = g_strdup(uri + strlen("file:"));
>> + if (file_parse_offset(addr->u.file.filename, &addr->u.file.offset,
>> + errp)) {
>> + return false;
>> + }
>> + } else {
>> + error_setg(errp, "unknown migration protocol: %s", uri);
>> + return false;
>> + }
>> +
>> + val->channel_type = MIGRATION_CHANNEL_TYPE_MAIN;
>> + val->addr = g_steal_pointer(&addr);
>> + *channel = g_steal_pointer(&val);
>> + return true;
>> +}
>> +
>> +bool migration_channel_parse_input(const char *uri,
>> + MigrationChannelList *channels,
>> + MigrationChannel **main_channelp,
>> + MigrationChannel **cpr_channelp,
>> + Error **errp)
>> +{
>> + if (!uri == !channels) {
>> + error_setg(errp, "need either 'uri' or 'channels' argument");
>> + return false;
>> + }
>> +
>> + if (channels) {
>> + return migrate_channels_parse(channels, main_channelp, cpr_channelp,
>> + errp);
>> + } else {
>> + return migrate_uri_parse(uri, main_channelp, errp);
>> + }
>> +}
>> diff --git a/migration/channel.h b/migration/channel.h
>> index b3276550b7..3724b0493a 100644
>> --- a/migration/channel.h
>> +++ b/migration/channel.h
>> @@ -52,8 +52,9 @@ static inline bool migration_connect_incoming(MigrationAddress *addr,
>> return migration_connect(addr, false, errp);
>> }
>>
>> -bool migrate_channels_parse(MigrationChannelList *channels,
>> - MigrationChannel **main_channelp,
>> - MigrationChannel **cpr_channelp,
>> - Error **errp);
>> +bool migration_channel_parse_input(const char *uri,
>> + MigrationChannelList *channels,
>> + MigrationChannel **main_channelp,
>> + MigrationChannel **cpr_channelp,
>> + Error **errp);
>> #endif
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 6064f1e5ea..15d8459a81 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -15,7 +15,6 @@
>>
>> #include "qemu/osdep.h"
>> #include "qemu/ctype.h"
>> -#include "qemu/cutils.h"
>> #include "qemu/error-report.h"
>> #include "qemu/main-loop.h"
>> #include "migration/blocker.h"
>> @@ -659,61 +658,6 @@ bool migrate_is_uri(const char *uri)
>> return *uri == ':';
>> }
>>
>> -bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
>> - Error **errp)
>> -{
>> - g_autoptr(MigrationChannel) val = g_new0(MigrationChannel, 1);
>> - g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1);
>> - InetSocketAddress *isock = &addr->u.rdma;
>> - strList **tail = &addr->u.exec.args;
>> -
>> - if (strstart(uri, "exec:", NULL)) {
>> - addr->transport = MIGRATION_ADDRESS_TYPE_EXEC;
>> -#ifdef WIN32
>> - QAPI_LIST_APPEND(tail, g_strdup(exec_get_cmd_path()));
>> - QAPI_LIST_APPEND(tail, g_strdup("/c"));
>> -#else
>> - QAPI_LIST_APPEND(tail, g_strdup("/bin/sh"));
>> - QAPI_LIST_APPEND(tail, g_strdup("-c"));
>> -#endif
>> - QAPI_LIST_APPEND(tail, g_strdup(uri + strlen("exec:")));
>> - } else if (strstart(uri, "rdma:", NULL)) {
>> - if (inet_parse(isock, uri + strlen("rdma:"), errp)) {
>> - qapi_free_InetSocketAddress(isock);
>> - return false;
>> - }
>> - addr->transport = MIGRATION_ADDRESS_TYPE_RDMA;
>> - } else if (strstart(uri, "tcp:", NULL) ||
>> - strstart(uri, "unix:", NULL) ||
>> - strstart(uri, "vsock:", NULL) ||
>> - strstart(uri, "fd:", NULL)) {
>> - addr->transport = MIGRATION_ADDRESS_TYPE_SOCKET;
>> - SocketAddress *saddr = socket_parse(uri, errp);
>> - if (!saddr) {
>> - return false;
>> - }
>> - addr->u.socket.type = saddr->type;
>> - addr->u.socket.u = saddr->u;
>> - /* Don't free the objects inside; their ownership moved to "addr" */
>> - g_free(saddr);
>> - } else if (strstart(uri, "file:", NULL)) {
>> - addr->transport = MIGRATION_ADDRESS_TYPE_FILE;
>> - addr->u.file.filename = g_strdup(uri + strlen("file:"));
>> - if (file_parse_offset(addr->u.file.filename, &addr->u.file.offset,
>> - errp)) {
>> - return false;
>> - }
>> - } else {
>> - error_setg(errp, "unknown migration protocol: %s", uri);
>> - return false;
>> - }
>> -
>> - val->channel_type = MIGRATION_CHANNEL_TYPE_MAIN;
>> - val->addr = g_steal_pointer(&addr);
>> - *channel = g_steal_pointer(&val);
>> - return true;
>> -}
>> -
>> static bool
>> migration_incoming_state_setup(MigrationIncomingState *mis, Error **errp)
>> {
>> @@ -744,27 +688,10 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
>> g_autoptr(MigrationChannel) main_ch = NULL;
>> MigrationIncomingState *mis = migration_incoming_get_current();
>>
>> - /*
>> - * Having preliminary checks for uri and channel
>> - */
>> - if (!uri == !channels) {
>> - error_setg(errp, "need either 'uri' or 'channels' argument");
>> + if (!migration_channel_parse_input(uri, channels, &main_ch, NULL, errp)) {
>> return;
>> }
>>
>> - if (channels) {
>> - if (!migrate_channels_parse(channels, &main_ch, NULL, errp)) {
>> - return;
>> - }
>> - }
>> -
>> - if (uri) {
>> - /* caller uses the old URI syntax */
>> - if (!migrate_uri_parse(uri, &main_ch, errp)) {
>> - return;
>> - }
>> - }
>> -
>> /* transport mechanism not suitable for migration? */
>> if (!migration_transport_compatible(main_ch->addr, errp)) {
>> return;
>> @@ -2124,27 +2051,11 @@ void qmp_migrate(const char *uri, bool has_channels,
>> g_autoptr(MigrationChannel) main_ch = NULL;
>> g_autoptr(MigrationChannel) cpr_ch = NULL;
>>
>> - /*
>> - * Having preliminary checks for uri and channel
>> - */
>> - if (!uri == !channels) {
>> - error_setg(errp, "need either 'uri' or 'channels' argument");
>> + if (!migration_channel_parse_input(uri, channels, &main_ch, &cpr_ch,
>> + errp)) {
>> return;
>> }
>>
>> - if (channels) {
>> - if (!migrate_channels_parse(channels, &main_ch, &cpr_ch, errp)) {
>> - return;
>> - }
>> - }
>> -
>> - if (uri) {
>> - /* caller uses the old URI syntax */
>> - if (!migrate_uri_parse(uri, &main_ch, errp)) {
>> - return;
>> - }
>> - }
>> -
>> /* transport mechanism not suitable for migration? */
>> if (!migration_transport_compatible(main_ch->addr, errp)) {
>> return;
>> --
>> 2.51.0
>>
next prev parent reply other threads:[~2025-12-29 21:22 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-26 21:19 [RFC PATCH 00/25] migration: Cleanup early connection code Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 01/25] migration: Remove redundant state change Fabiano Rosas
2025-12-29 15:22 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 02/25] migration: Fix state change at migration_channel_process_incoming Fabiano Rosas
2025-12-29 15:32 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 03/25] migration/tls: Remove unused parameter Fabiano Rosas
2025-12-29 15:33 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 04/25] migration: Move multifd_recv_setup call Fabiano Rosas
2025-12-29 15:51 ` Peter Xu
2025-12-29 19:21 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 05/25] migration: Cleanup TLS handshake hostname passing Fabiano Rosas
2025-12-29 16:12 ` Peter Xu
2025-12-29 19:38 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 06/25] migration: Move postcopy_try_recover into migration_incoming_process Fabiano Rosas
2025-12-29 16:15 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 07/25] migration: Use migrate_mode() to query for cpr-transfer Fabiano Rosas
2025-12-29 16:33 ` Peter Xu
2025-12-29 19:23 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 08/25] migration: Free the error earlier in the resume case Fabiano Rosas
2025-12-29 16:39 ` [RFC PATCH 08/25] migration: Free the error earlier in the resume case' Peter Xu
2025-12-26 21:19 ` [RFC PATCH 09/25] migration: Move error reporting out of migration_cleanup Fabiano Rosas
2025-12-29 16:45 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 10/25] migration: Expand migration_connect_error_propagate to cover cancelling Fabiano Rosas
2025-12-29 17:12 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 11/25] migration: yank: Move register instance earlier Fabiano Rosas
2025-12-29 17:17 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 12/25] migration: Fold migration_cleanup() into migration_connect_error_propagate() Fabiano Rosas
2025-12-29 18:42 ` Peter Xu
2025-12-29 19:26 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 13/25] migration: Handle error in the early async paths Fabiano Rosas
2025-12-29 19:08 ` Peter Xu
2025-12-29 19:35 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 14/25] migration: Remove QEMUFile from channel.c Fabiano Rosas
2025-12-29 19:36 ` Peter Xu
2025-12-29 19:51 ` Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 15/25] migration/channel: Rename migration_channel_connect Fabiano Rosas
2025-12-29 19:40 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 16/25] migration: Rename instances of start Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 17/25] migration: Move channel code to channel.c Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 18/25] migration: Move transport connection code into channel.c Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 19/25] migration/channel: Make synchronous calls evident Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 20/25] migration/channel: Use switch statements in outgoing code Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 21/25] migration/channel: Cleanup early passing of MigrationState Fabiano Rosas
2025-12-26 21:19 ` [RFC PATCH 22/25] migration/channel: Merge both sides of the connection initiation code Fabiano Rosas
2025-12-29 20:06 ` Peter Xu
2025-12-29 21:14 ` Fabiano Rosas
2025-12-29 22:05 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 23/25] migration: Move channel parsing to channel.c Fabiano Rosas
2025-12-29 21:01 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 24/25] migration: Move URI " Fabiano Rosas
2025-12-29 21:08 ` Peter Xu
2025-12-29 21:22 ` Fabiano Rosas [this message]
2025-12-29 22:11 ` Peter Xu
2025-12-26 21:19 ` [RFC PATCH 25/25] migration: Remove qmp_migrate_finish Fabiano Rosas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87344t7zlv.fsf@suse.de \
--to=farosas@suse.de \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.