* [PATCH v3 01/25] migration: Remove redundant state change
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-13 12:33 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming Fabiano Rosas
` (23 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
If local_err is set, migration_connect_error_propagate() will be
called and that function already has a state transtion from SETUP to
FAILED.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 9d1bf5d276..c45393f40e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2326,8 +2326,6 @@ static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
file_start_outgoing_migration(s, &addr->u.file, &local_err);
} else {
error_setg(&local_err, "uri is not a valid migration protocol");
- migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
- MIGRATION_STATUS_FAILED);
}
if (local_err) {
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 01/25] migration: Remove redundant state change
2026-01-09 12:40 ` [PATCH v3 01/25] migration: Remove redundant state change Fabiano Rosas
@ 2026-01-13 12:33 ` Prasad Pandit
2026-01-13 13:25 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-13 12:33 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
> If local_err is set, migration_connect_error_propagate() will be
> called and that function already has a state transtion from SETUP to
> FAILED.
* transtion -> transition.
> diff --git a/migration/migration.c b/migration/migration.c
> index 9d1bf5d276..c45393f40e 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2326,8 +2326,6 @@ static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
> file_start_outgoing_migration(s, &addr->u.file, &local_err);
> } else {
> error_setg(&local_err, "uri is not a valid migration protocol");
> - migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
> - MIGRATION_STATUS_FAILED);
> }
* Maybe we could remove this last '} else {' block altogether? The
'addr->transport == ' check could be moved to the
migrate_transport_compatible() function (OR near there), which is
called after addr = channel->addr.
* Saying that - "uri is invalid" - in qmp_migrate_finish() raises a
question - how did we reach till _migrate_finish() if uri was invalid?
Is qmp_migrate_finish() called by libvirtd(8) OR external users via
QMP? If not, if it is an internal only function to just start
migration, it could be renamed appropriately without qmp_ prefix -
migrate_start() OR begin_migration() something to the effect that says
it starts migration, rather than finish it. migrate_finish() function
calling *_start_outgoing_migration() reads contradictory/opposite.
(I'm going through the rest of the patches in this series.)
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 01/25] migration: Remove redundant state change
2026-01-13 12:33 ` Prasad Pandit
@ 2026-01-13 13:25 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-13 13:25 UTC (permalink / raw)
To: Prasad Pandit; +Cc: qemu-devel, peterx, berrange
Prasad Pandit <ppandit@redhat.com> writes:
> On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
>> If local_err is set, migration_connect_error_propagate() will be
>> called and that function already has a state transtion from SETUP to
>> FAILED.
>
> * transtion -> transition.
>
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 9d1bf5d276..c45393f40e 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -2326,8 +2326,6 @@ static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
>> file_start_outgoing_migration(s, &addr->u.file, &local_err);
>> } else {
>> error_setg(&local_err, "uri is not a valid migration protocol");
>> - migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
>> - MIGRATION_STATUS_FAILED);
>> }
>
> * Maybe we could remove this last '} else {' block altogether? The
> 'addr->transport == ' check could be moved to the
> migrate_transport_compatible() function (OR near there), which is
> called after addr = channel->addr.
>
This needs to be here (i.e. in two parts) because of the CPR transfer
flow.
> * Saying that - "uri is invalid" - in qmp_migrate_finish() raises a
> question - how did we reach till _migrate_finish() if uri was invalid?
The split in qmp_migrate/qmp_migrate_finish is so that the connection
and migration-start steps can be separated by the CPR transfer hangup
signal. For regular migration it's still as if this were a single
routine.
> Is qmp_migrate_finish() called by libvirtd(8) OR external users via
> QMP? If not, if it is an internal only function to just start
> migration, it could be renamed appropriately without qmp_ prefix -
> migrate_start() OR begin_migration() something to the effect that says
> it starts migration, rather than finish it. migrate_finish() function
> calling *_start_outgoing_migration() reads contradictory/opposite.
>
Yes, patch 24 at the end of the series takes care of this. I first need
to put some things in place so that we can reuse the connection code for
both the regular migration and cpr-transfer.
> (I'm going through the rest of the patches in this series.)
>
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
2026-01-09 12:40 ` [PATCH v3 01/25] migration: Remove redundant state change Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-13 12:39 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 03/25] migration/tls: Remove unused parameter Fabiano Rosas
` (22 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
When the incoming migration fails during the channel connection phase,
the state transition to FAILED is currently being done in the
MigrationState->state, but the MigrationIncomingState->state is the
one that should be used.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/migration/channel.c b/migration/channel.c
index 92435fa7f7..4768c71455 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -48,7 +48,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
if (local_err) {
error_report_err(local_err);
- migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
+ migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED);
if (mis->exit_on_error) {
exit(EXIT_FAILURE);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming
2026-01-09 12:40 ` [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming Fabiano Rosas
@ 2026-01-13 12:39 ` Prasad Pandit
2026-01-13 13:27 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-13 12:39 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
> When the incoming migration fails during the channel connection phase,
> the state transition to FAILED is currently being done in the
> MigrationState->state, but the MigrationIncomingState->state is the
> one that should be used.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 92435fa7f7..4768c71455 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -48,7 +48,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
>
> if (local_err) {
> error_report_err(local_err);
> - migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
> + migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED);
> if (mis->exit_on_error) {
> exit(EXIT_FAILURE);
> }
* Change looks okay. (/me makes a note to see if we could combine
MigrationState and MigrationIncomingState, why couldn't we use the
same struct/object on both source and destination sides?).
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming
2026-01-13 12:39 ` Prasad Pandit
@ 2026-01-13 13:27 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-13 13:27 UTC (permalink / raw)
To: Prasad Pandit; +Cc: qemu-devel, peterx, berrange
Prasad Pandit <ppandit@redhat.com> writes:
> On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
>> When the incoming migration fails during the channel connection phase,
>> the state transition to FAILED is currently being done in the
>> MigrationState->state, but the MigrationIncomingState->state is the
>> one that should be used.
>>
>> Reviewed-by: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>> ---
>> migration/channel.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/migration/channel.c b/migration/channel.c
>> index 92435fa7f7..4768c71455 100644
>> --- a/migration/channel.c
>> +++ b/migration/channel.c
>> @@ -48,7 +48,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
>>
>> if (local_err) {
>> error_report_err(local_err);
>> - migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
>> + migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED);
>> if (mis->exit_on_error) {
>> exit(EXIT_FAILURE);
>> }
>
> * Change looks okay. (/me makes a note to see if we could combine
> MigrationState and MigrationIncomingState, why couldn't we use the
> same struct/object on both source and destination sides?).
>
The entire structs are a bit big for them to be duplicated. We could
certainly combine individual fields where it makes sense, or extract
some fields into their own structures that only get used in local
contexts. Work to be done.
> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
>
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 03/25] migration/tls: Remove unused parameter
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
2026-01-09 12:40 ` [PATCH v3 01/25] migration: Remove redundant state change Fabiano Rosas
2026-01-09 12:40 ` [PATCH v3 02/25] migration: Fix state change at migration_channel_process_incoming Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:37 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing Fabiano Rosas
` (21 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
MigrationState is not used at migration_tls_channel_process_incoming().
The last usage was removed by commit 3f461a0c0b ("migration: Drop
unused parameter for migration_tls_get_creds()")
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 3 +--
migration/tls.c | 4 +---
migration/tls.h | 4 +---
3 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index 4768c71455..b4ab676048 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -32,7 +32,6 @@
*/
void migration_channel_process_incoming(QIOChannel *ioc)
{
- MigrationState *s = migrate_get_current();
MigrationIncomingState *mis = migration_incoming_get_current();
Error *local_err = NULL;
@@ -40,7 +39,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
ioc, object_get_typename(OBJECT(ioc)));
if (migrate_channel_requires_tls_upgrade(ioc)) {
- migration_tls_channel_process_incoming(s, ioc, &local_err);
+ migration_tls_channel_process_incoming(ioc, &local_err);
} else {
migration_ioc_register_yank(ioc);
migration_ioc_process_incoming(ioc, &local_err);
diff --git a/migration/tls.c b/migration/tls.c
index 56b5d1cc90..1df31bdcbb 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -71,9 +71,7 @@ static void migration_tls_incoming_handshake(QIOTask *task,
object_unref(OBJECT(ioc));
}
-void migration_tls_channel_process_incoming(MigrationState *s,
- QIOChannel *ioc,
- Error **errp)
+void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp)
{
QCryptoTLSCreds *creds;
QIOChannelTLS *tioc;
diff --git a/migration/tls.h b/migration/tls.h
index 58b25e1228..7607cfe803 100644
--- a/migration/tls.h
+++ b/migration/tls.h
@@ -24,9 +24,7 @@
#include "io/channel.h"
#include "io/channel-tls.h"
-void migration_tls_channel_process_incoming(MigrationState *s,
- QIOChannel *ioc,
- Error **errp);
+void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
const char *hostname,
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 03/25] migration/tls: Remove unused parameter
2026-01-09 12:40 ` [PATCH v3 03/25] migration/tls: Remove unused parameter Fabiano Rosas
@ 2026-01-19 12:37 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:37 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:14, Fabiano Rosas <farosas@suse.de> wrote:
> MigrationState is not used at migration_tls_channel_process_incoming().
* MigrationState -> MigrationState parameter
* at -> in
> The last usage was removed by commit 3f461a0c0b ("migration: Drop
> unused parameter for migration_tls_get_creds()")
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 3 +--
> migration/tls.c | 4 +---
> migration/tls.h | 4 +---
> 3 files changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 4768c71455..b4ab676048 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -32,7 +32,6 @@
> */
> void migration_channel_process_incoming(QIOChannel *ioc)
> {
> - MigrationState *s = migrate_get_current();
> MigrationIncomingState *mis = migration_incoming_get_current();
> Error *local_err = NULL;
>
> @@ -40,7 +39,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> ioc, object_get_typename(OBJECT(ioc)));
>
> if (migrate_channel_requires_tls_upgrade(ioc)) {
> - migration_tls_channel_process_incoming(s, ioc, &local_err);
> + migration_tls_channel_process_incoming(ioc, &local_err);
> } else {
> migration_ioc_register_yank(ioc);
> migration_ioc_process_incoming(ioc, &local_err);
> diff --git a/migration/tls.c b/migration/tls.c
> index 56b5d1cc90..1df31bdcbb 100644
> --- a/migration/tls.c
> +++ b/migration/tls.c
> @@ -71,9 +71,7 @@ static void migration_tls_incoming_handshake(QIOTask *task,
> object_unref(OBJECT(ioc));
> }
>
> -void migration_tls_channel_process_incoming(MigrationState *s,
> - QIOChannel *ioc,
> - Error **errp)
> +void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp)
> {
> QCryptoTLSCreds *creds;
> QIOChannelTLS *tioc;
> diff --git a/migration/tls.h b/migration/tls.h
> index 58b25e1228..7607cfe803 100644
> --- a/migration/tls.h
> +++ b/migration/tls.h
> @@ -24,9 +24,7 @@
> #include "io/channel.h"
> #include "io/channel-tls.h"
>
> -void migration_tls_channel_process_incoming(MigrationState *s,
> - QIOChannel *ioc,
> - Error **errp);
> +void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
>
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> const char *hostname,
> --
* Looks right.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (2 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 03/25] migration/tls: Remove unused parameter Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:02 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 05/25] migration: Move postcopy_try_recover into migration_incoming_process Fabiano Rosas
` (20 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
The TLS hostname is doing a tour around the world just to be cached
into s->hostname. We're already abusing MigrationState by doing that,
so incorporate the s->hostname into migration_tls_hostname() and stop
passing the string around.
The old route was roughly:
-transport code (socket.c, fd.c, etc):
if (SOCKET_ADDRESS_TYPE_INET)
hostname = saddr->u.inet.host
else
hostname = NULL
migration_channel_connect(..., hostname)
s->hostname = hostname;
migration_tls_client_create(..., hostname)
if (migrate_tls_hostname())
qio_channel_tls_new_client(migrate_tls_hostname())
else
qio_channel_tls_new_client(hostname)
-postcopy_preempt_setup:
postcopy_preempt_send_channel_new
migration_tls_client_create(..., s->hostname)
New route is:
-socket.c only:
if SOCKET_ADDRESS_TYPE_INET
s->hostname = saddr->u.inet.host
migration_channel_connect()
migration_tls_client_create()
qio_channel_tls_new_client(migrate_tls_hostname())
-postcopy_preempt_setup:
postcopy_preempt_send_channel_new
migration_tls_client_create()
qio_channel_tls_new_client(migrate_tls_hostname())
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 6 ++----
migration/channel.h | 1 -
migration/exec.c | 2 +-
migration/fd.c | 2 +-
migration/file.c | 2 +-
migration/multifd.c | 9 +++------
migration/options.c | 5 +++++
migration/postcopy-ram.c | 2 +-
migration/socket.c | 9 +++------
migration/tls.c | 17 ++++-------------
migration/tls.h | 2 --
migration/trace-events | 10 +++++-----
12 files changed, 26 insertions(+), 41 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index b4ab676048..ba14f66d85 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -60,20 +60,18 @@ void migration_channel_process_incoming(QIOChannel *ioc)
*
* @s: Current migration state
* @ioc: Channel to which we are connecting
- * @hostname: Where we want to connect
* @error: Error indicating failure to connect, free'd here
*/
void migration_channel_connect(MigrationState *s,
QIOChannel *ioc,
- const char *hostname,
Error *error)
{
trace_migration_set_outgoing_channel(
- ioc, object_get_typename(OBJECT(ioc)), hostname, error);
+ ioc, object_get_typename(OBJECT(ioc)), error);
if (!error) {
if (migrate_channel_requires_tls_upgrade(ioc)) {
- migration_tls_channel_connect(s, ioc, hostname, &error);
+ migration_tls_channel_connect(s, ioc, &error);
if (!error) {
/* tls_channel_connect will call back to this
diff --git a/migration/channel.h b/migration/channel.h
index 5bdb8208a7..2215091323 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -22,7 +22,6 @@ void migration_channel_process_incoming(QIOChannel *ioc);
void migration_channel_connect(MigrationState *s,
QIOChannel *ioc,
- const char *hostname,
Error *error_in);
int migration_channel_read_peek(QIOChannel *ioc,
diff --git a/migration/exec.c b/migration/exec.c
index 20e6cccf8c..78fe0fff13 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
}
qio_channel_set_name(ioc, "migration-exec-outgoing");
- migration_channel_connect(s, ioc, NULL, NULL);
+ migration_channel_connect(s, ioc, NULL);
object_unref(OBJECT(ioc));
}
diff --git a/migration/fd.c b/migration/fd.c
index 9bf9be6acb..c956b260a4 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
}
qio_channel_set_name(ioc, "migration-fd-outgoing");
- migration_channel_connect(s, ioc, NULL, NULL);
+ migration_channel_connect(s, ioc, NULL);
object_unref(OBJECT(ioc));
}
diff --git a/migration/file.c b/migration/file.c
index bb8031e3c7..c490f2b219 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
return;
}
qio_channel_set_name(ioc, "migration-file-outgoing");
- migration_channel_connect(s, ioc, NULL, NULL);
+ migration_channel_connect(s, ioc, NULL);
}
static gboolean file_accept_incoming_migration(QIOChannel *ioc,
diff --git a/migration/multifd.c b/migration/multifd.c
index bf6da85af8..3fb1a07ba9 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -814,12 +814,10 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
QIOChannel *ioc,
Error **errp)
{
- MigrationState *s = migrate_get_current();
- const char *hostname = s->hostname;
MultiFDTLSThreadArgs *args;
QIOChannelTLS *tioc;
- tioc = migration_tls_client_create(ioc, hostname, errp);
+ tioc = migration_tls_client_create(ioc, errp);
if (!tioc) {
return false;
}
@@ -829,7 +827,7 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
* created TLS channel, which has already taken a reference.
*/
object_unref(OBJECT(ioc));
- trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
+ trace_multifd_tls_outgoing_handshake_start(ioc, tioc);
qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
args = g_new0(MultiFDTLSThreadArgs, 1);
@@ -876,8 +874,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
goto out;
}
- trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)),
- migrate_get_current()->hostname);
+ trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
if (migrate_channel_requires_tls_upgrade(ioc)) {
ret = multifd_tls_channel_connect(p, ioc, &local_err);
diff --git a/migration/options.c b/migration/options.c
index 9a5a39c886..881034c289 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -956,6 +956,11 @@ const char *migrate_tls_hostname(void)
return s->parameters.tls_hostname->u.s;
}
+ /* hostname saved from a previously connected channel */
+ if (s->hostname) {
+ return s->hostname;
+ }
+
return NULL;
}
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 98a98138be..7afb42bd27 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -1966,7 +1966,7 @@ postcopy_preempt_send_channel_new(QIOTask *task, gpointer opaque)
}
if (migrate_channel_requires_tls_upgrade(ioc)) {
- tioc = migration_tls_client_create(ioc, s->hostname, &local_err);
+ tioc = migration_tls_client_create(ioc, &local_err);
if (!tioc) {
goto out;
}
diff --git a/migration/socket.c b/migration/socket.c
index 9e379bf56f..426f363b99 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -44,7 +44,6 @@ void socket_send_channel_create(QIOTaskFunc f, void *data)
struct SocketConnectData {
MigrationState *s;
- char *hostname;
};
static void socket_connect_data_free(void *opaque)
@@ -53,7 +52,6 @@ static void socket_connect_data_free(void *opaque)
if (!data) {
return;
}
- g_free(data->hostname);
g_free(data);
}
@@ -69,7 +67,7 @@ static void socket_outgoing_migration(QIOTask *task,
goto out;
}
- trace_migration_socket_outgoing_connected(data->hostname);
+ trace_migration_socket_outgoing_connected();
if (migrate_zero_copy_send() &&
!qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
@@ -77,7 +75,7 @@ static void socket_outgoing_migration(QIOTask *task,
}
out:
- migration_channel_connect(data->s, sioc, data->hostname, err);
+ migration_channel_connect(data->s, sioc, err);
object_unref(OBJECT(sioc));
}
@@ -96,7 +94,7 @@ void socket_start_outgoing_migration(MigrationState *s,
outgoing_args.saddr = addr;
if (saddr->type == SOCKET_ADDRESS_TYPE_INET) {
- data->hostname = g_strdup(saddr->u.inet.host);
+ s->hostname = g_strdup(saddr->u.inet.host);
}
qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-outgoing");
@@ -180,4 +178,3 @@ void socket_start_incoming_migration(SocketAddress *saddr,
qapi_free_SocketAddress(address);
}
}
-
diff --git a/migration/tls.c b/migration/tls.c
index 1df31bdcbb..82f58cbc78 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -112,12 +112,11 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
} else {
trace_migration_tls_outgoing_handshake_complete();
}
- migration_channel_connect(s, ioc, NULL, err);
+ migration_channel_connect(s, ioc, err);
object_unref(OBJECT(ioc));
}
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
- const char *hostname,
Error **errp)
{
QCryptoTLSCreds *creds;
@@ -127,29 +126,21 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
return NULL;
}
- const char *tls_hostname = migrate_tls_hostname();
- if (tls_hostname) {
- hostname = tls_hostname;
- }
-
- return qio_channel_tls_new_client(ioc, creds, hostname, errp);
+ return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);
}
void migration_tls_channel_connect(MigrationState *s,
QIOChannel *ioc,
- const char *hostname,
Error **errp)
{
QIOChannelTLS *tioc;
- tioc = migration_tls_client_create(ioc, hostname, errp);
+ tioc = migration_tls_client_create(ioc, errp);
if (!tioc) {
return;
}
- /* Save hostname into MigrationState for handshake */
- s->hostname = g_strdup(hostname);
- trace_migration_tls_outgoing_handshake_start(hostname);
+ trace_migration_tls_outgoing_handshake_start();
qio_channel_set_name(QIO_CHANNEL(tioc), "migration-tls-outgoing");
if (migrate_postcopy_ram() || migrate_return_path()) {
diff --git a/migration/tls.h b/migration/tls.h
index 7607cfe803..7cd9c76013 100644
--- a/migration/tls.h
+++ b/migration/tls.h
@@ -27,12 +27,10 @@
void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
- const char *hostname,
Error **errp);
void migration_tls_channel_connect(MigrationState *s,
QIOChannel *ioc,
- const char *hostname,
Error **errp);
void migration_tls_channel_end(QIOChannel *ioc, Error **errp);
/* Whether the QIO channel requires further TLS handshake? */
diff --git a/migration/trace-events b/migration/trace-events
index bf11b62b17..da8f909cac 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -149,10 +149,10 @@ multifd_send_sync_main_wait(uint8_t id) "channel %u"
multifd_send_terminate_threads(void) ""
multifd_send_thread_end(uint8_t id, uint64_t packets) "channel %u packets %" PRIu64
multifd_send_thread_start(uint8_t id) "%u"
-multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char *hostname) "ioc=%p tioc=%p hostname=%s"
+multifd_tls_outgoing_handshake_start(void *ioc, void *tioc) "ioc=%p tioc=%p"
multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p err=%s"
multifd_tls_outgoing_handshake_complete(void *ioc) "ioc=%p"
-multifd_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname) "ioc=%p ioctype=%s hostname=%s"
+multifd_set_outgoing_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
# migration.c
migrate_set_state(const char *new_state) "new state %s"
@@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)
# channel.c
migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
-migration_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname, void *err) "ioc=%p ioctype=%s hostname=%s err=%p"
+migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err) "ioc=%p ioctype=%s err=%p"
# global_state.c
migrate_state_too_big(void) ""
@@ -328,11 +328,11 @@ migration_file_incoming(const char *filename) "filename=%s"
# socket.c
migration_socket_incoming_accepted(void) ""
-migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
+migration_socket_outgoing_connected(void) ""
migration_socket_outgoing_error(const char *err) "error=%s"
# tls.c
-migration_tls_outgoing_handshake_start(const char *hostname) "hostname=%s"
+migration_tls_outgoing_handshake_start(void) ""
migration_tls_outgoing_handshake_error(const char *err) "err=%s"
migration_tls_outgoing_handshake_complete(void) ""
migration_tls_incoming_handshake_start(void) ""
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing
2026-01-09 12:40 ` [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing Fabiano Rosas
@ 2026-01-20 11:02 ` Prasad Pandit
2026-01-20 11:11 ` Daniel P. Berrangé
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:02 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:18, Fabiano Rosas <farosas@suse.de> wrote:
> The TLS hostname is doing a tour around the world just to be cached
> into s->hostname. We're already abusing MigrationState by doing that,
> so incorporate the s->hostname into migration_tls_hostname() and stop
> passing the string around.
* I get the idea of not passing 's->hostname' around as a parameter, but:
- migrate_tls_hostname() already returns '->tls_hostname->u.s',
why are we making it return 's->hostname' too?
- How are 'tls_hostname->u.s' and 's->hostname' different?
+ virsh(1) migrate has:
--tls-destination <string> override the destination host name
used for TLS verification
* IIUC, when --tls-destination is supplied, s->hostname and
tls_hostname are different, otherwise they are the same? If that is
the case, could we set tls_hostname = s->hostname when
params->tls_hostname is not defined below?
===
static void migrate_params_test_apply(MigrationParameters *params,
MigrationParameters *dest)
{
if (params->tls_hostname) {
dest->tls_hostname = QAPI_CLONE(StrOrNull, params->tls_hostname);
} else {
/* clear the reference, it's owned by s->parameters */
dest->tls_hostname = NULL;
}
...
static void migrate_params_apply(MigrationParameters *params)
{
...
if (params->tls_hostname) {
qapi_free_StrOrNull(s->parameters.tls_hostname);
s->parameters.tls_hostname = QAPI_CLONE(StrOrNull,
params->tls_hostname);
}
...
}
===
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 6 ++----
> migration/channel.h | 1 -
> migration/exec.c | 2 +-
> migration/fd.c | 2 +-
> migration/file.c | 2 +-
> migration/multifd.c | 9 +++------
> migration/options.c | 5 +++++
> migration/postcopy-ram.c | 2 +-
> migration/socket.c | 9 +++------
> migration/tls.c | 17 ++++-------------
> migration/tls.h | 2 --
> migration/trace-events | 10 +++++-----
> 12 files changed, 26 insertions(+), 41 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index b4ab676048..ba14f66d85 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -60,20 +60,18 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> *
> * @s: Current migration state
> * @ioc: Channel to which we are connecting
> - * @hostname: Where we want to connect
> * @error: Error indicating failure to connect, free'd here
> */
> void migration_channel_connect(MigrationState *s,
> QIOChannel *ioc,
> - const char *hostname,
> Error *error)
> {
> trace_migration_set_outgoing_channel(
> - ioc, object_get_typename(OBJECT(ioc)), hostname, error);
> + ioc, object_get_typename(OBJECT(ioc)), error);
>
> if (!error) {
> if (migrate_channel_requires_tls_upgrade(ioc)) {
> - migration_tls_channel_connect(s, ioc, hostname, &error);
> + migration_tls_channel_connect(s, ioc, &error);
>
> if (!error) {
> /* tls_channel_connect will call back to this
> diff --git a/migration/channel.h b/migration/channel.h
> index 5bdb8208a7..2215091323 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -22,7 +22,6 @@ void migration_channel_process_incoming(QIOChannel *ioc);
>
> void migration_channel_connect(MigrationState *s,
> QIOChannel *ioc,
> - const char *hostname,
> Error *error_in);
>
> int migration_channel_read_peek(QIOChannel *ioc,
> diff --git a/migration/exec.c b/migration/exec.c
> index 20e6cccf8c..78fe0fff13 100644
> --- a/migration/exec.c
> +++ b/migration/exec.c
> @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
> }
>
> qio_channel_set_name(ioc, "migration-exec-outgoing");
> - migration_channel_connect(s, ioc, NULL, NULL);
> + migration_channel_connect(s, ioc, NULL);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/fd.c b/migration/fd.c
> index 9bf9be6acb..c956b260a4 100644
> --- a/migration/fd.c
> +++ b/migration/fd.c
> @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
> }
>
> qio_channel_set_name(ioc, "migration-fd-outgoing");
> - migration_channel_connect(s, ioc, NULL, NULL);
> + migration_channel_connect(s, ioc, NULL);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/file.c b/migration/file.c
> index bb8031e3c7..c490f2b219 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
> return;
> }
> qio_channel_set_name(ioc, "migration-file-outgoing");
> - migration_channel_connect(s, ioc, NULL, NULL);
> + migration_channel_connect(s, ioc, NULL);
> }
>
> static gboolean file_accept_incoming_migration(QIOChannel *ioc,
> diff --git a/migration/multifd.c b/migration/multifd.c
> index bf6da85af8..3fb1a07ba9 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -814,12 +814,10 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
> QIOChannel *ioc,
> Error **errp)
> {
> - MigrationState *s = migrate_get_current();
> - const char *hostname = s->hostname;
> MultiFDTLSThreadArgs *args;
> QIOChannelTLS *tioc;
>
> - tioc = migration_tls_client_create(ioc, hostname, errp);
> + tioc = migration_tls_client_create(ioc, errp);
> if (!tioc) {
> return false;
> }
> @@ -829,7 +827,7 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
> * created TLS channel, which has already taken a reference.
> */
> object_unref(OBJECT(ioc));
> - trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
> + trace_multifd_tls_outgoing_handshake_start(ioc, tioc);
> qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
>
> args = g_new0(MultiFDTLSThreadArgs, 1);
> @@ -876,8 +874,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
> goto out;
> }
>
> - trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)),
> - migrate_get_current()->hostname);
> + trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
>
> if (migrate_channel_requires_tls_upgrade(ioc)) {
> ret = multifd_tls_channel_connect(p, ioc, &local_err);
> diff --git a/migration/options.c b/migration/options.c
> index 9a5a39c886..881034c289 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -956,6 +956,11 @@ const char *migrate_tls_hostname(void)
> return s->parameters.tls_hostname->u.s;
> }
>
> + /* hostname saved from a previously connected channel */
> + if (s->hostname) {
> + return s->hostname;
> + }
> +
* Maybe this return 's->hostname' can be avoided by setting
tls_hostname = s->hostname at the initialisation stage. If
'tls_hostname' and 's->hostname' are different, will the
migrate_tls_hostname() callers work correctly with s->hostname?
> return NULL;
> }
>
> diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
> index 98a98138be..7afb42bd27 100644
> --- a/migration/postcopy-ram.c
> +++ b/migration/postcopy-ram.c
> @@ -1966,7 +1966,7 @@ postcopy_preempt_send_channel_new(QIOTask *task, gpointer opaque)
> }
>
> if (migrate_channel_requires_tls_upgrade(ioc)) {
> - tioc = migration_tls_client_create(ioc, s->hostname, &local_err);
> + tioc = migration_tls_client_create(ioc, &local_err);
> if (!tioc) {
> goto out;
> }
> diff --git a/migration/socket.c b/migration/socket.c
> index 9e379bf56f..426f363b99 100644
> --- a/migration/socket.c
> +++ b/migration/socket.c
> @@ -44,7 +44,6 @@ void socket_send_channel_create(QIOTaskFunc f, void *data)
>
> struct SocketConnectData {
> MigrationState *s;
> - char *hostname;
> };
>
> static void socket_connect_data_free(void *opaque)
> @@ -53,7 +52,6 @@ static void socket_connect_data_free(void *opaque)
> if (!data) {
> return;
> }
> - g_free(data->hostname);
> g_free(data);
> }
>
> @@ -69,7 +67,7 @@ static void socket_outgoing_migration(QIOTask *task,
> goto out;
> }
>
> - trace_migration_socket_outgoing_connected(data->hostname);
> + trace_migration_socket_outgoing_connected();
>
> if (migrate_zero_copy_send() &&
> !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
> @@ -77,7 +75,7 @@ static void socket_outgoing_migration(QIOTask *task,
> }
>
> out:
> - migration_channel_connect(data->s, sioc, data->hostname, err);
> + migration_channel_connect(data->s, sioc, err);
> object_unref(OBJECT(sioc));
> }
>
> @@ -96,7 +94,7 @@ void socket_start_outgoing_migration(MigrationState *s,
> outgoing_args.saddr = addr;
>
> if (saddr->type == SOCKET_ADDRESS_TYPE_INET) {
> - data->hostname = g_strdup(saddr->u.inet.host);
> + s->hostname = g_strdup(saddr->u.inet.host);
> }
>
> qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-outgoing");
> @@ -180,4 +178,3 @@ void socket_start_incoming_migration(SocketAddress *saddr,
> qapi_free_SocketAddress(address);
> }
> }
> -
> diff --git a/migration/tls.c b/migration/tls.c
> index 1df31bdcbb..82f58cbc78 100644
> --- a/migration/tls.c
> +++ b/migration/tls.c
> @@ -112,12 +112,11 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
> } else {
> trace_migration_tls_outgoing_handshake_complete();
> }
> - migration_channel_connect(s, ioc, NULL, err);
> + migration_channel_connect(s, ioc, err);
> object_unref(OBJECT(ioc));
> }
>
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> - const char *hostname,
> Error **errp)
> {
> QCryptoTLSCreds *creds;
> @@ -127,29 +126,21 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> return NULL;
> }
>
> - const char *tls_hostname = migrate_tls_hostname();
> - if (tls_hostname) {
> - hostname = tls_hostname;
> - }
> -
> - return qio_channel_tls_new_client(ioc, creds, hostname, errp);
> + return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);
> }
>
> void migration_tls_channel_connect(MigrationState *s,
> QIOChannel *ioc,
> - const char *hostname,
> Error **errp)
> {
> QIOChannelTLS *tioc;
>
> - tioc = migration_tls_client_create(ioc, hostname, errp);
> + tioc = migration_tls_client_create(ioc, errp);
> if (!tioc) {
> return;
> }
>
> - /* Save hostname into MigrationState for handshake */
> - s->hostname = g_strdup(hostname);
> - trace_migration_tls_outgoing_handshake_start(hostname);
> + trace_migration_tls_outgoing_handshake_start();
> qio_channel_set_name(QIO_CHANNEL(tioc), "migration-tls-outgoing");
>
> if (migrate_postcopy_ram() || migrate_return_path()) {
> diff --git a/migration/tls.h b/migration/tls.h
> index 7607cfe803..7cd9c76013 100644
> --- a/migration/tls.h
> +++ b/migration/tls.h
> @@ -27,12 +27,10 @@
> void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
>
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> - const char *hostname,
> Error **errp);
>
> void migration_tls_channel_connect(MigrationState *s,
> QIOChannel *ioc,
> - const char *hostname,
> Error **errp);
> void migration_tls_channel_end(QIOChannel *ioc, Error **errp);
> /* Whether the QIO channel requires further TLS handshake? */
> diff --git a/migration/trace-events b/migration/trace-events
> index bf11b62b17..da8f909cac 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -149,10 +149,10 @@ multifd_send_sync_main_wait(uint8_t id) "channel %u"
> multifd_send_terminate_threads(void) ""
> multifd_send_thread_end(uint8_t id, uint64_t packets) "channel %u packets %" PRIu64
> multifd_send_thread_start(uint8_t id) "%u"
> -multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char *hostname) "ioc=%p tioc=%p hostname=%s"
> +multifd_tls_outgoing_handshake_start(void *ioc, void *tioc) "ioc=%p tioc=%p"
> multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p err=%s"
> multifd_tls_outgoing_handshake_complete(void *ioc) "ioc=%p"
> -multifd_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname) "ioc=%p ioctype=%s hostname=%s"
> +multifd_set_outgoing_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
>
> # migration.c
> migrate_set_state(const char *new_state) "new state %s"
> @@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)
>
> # channel.c
> migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
> -migration_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname, void *err) "ioc=%p ioctype=%s hostname=%s err=%p"
> +migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err) "ioc=%p ioctype=%s err=%p"
>
> # global_state.c
> migrate_state_too_big(void) ""
> @@ -328,11 +328,11 @@ migration_file_incoming(const char *filename) "filename=%s"
>
> # socket.c
> migration_socket_incoming_accepted(void) ""
> -migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
> +migration_socket_outgoing_connected(void) ""
> migration_socket_outgoing_error(const char *err) "error=%s"
>
> # tls.c
> -migration_tls_outgoing_handshake_start(const char *hostname) "hostname=%s"
> +migration_tls_outgoing_handshake_start(void) ""
> migration_tls_outgoing_handshake_error(const char *err) "err=%s"
> migration_tls_outgoing_handshake_complete(void) ""
> migration_tls_incoming_handshake_start(void) ""
> --
* Otherwise change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing
2026-01-20 11:02 ` Prasad Pandit
@ 2026-01-20 11:11 ` Daniel P. Berrangé
2026-01-20 11:37 ` Prasad Pandit
0 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-01-20 11:11 UTC (permalink / raw)
To: Prasad Pandit; +Cc: Fabiano Rosas, qemu-devel, peterx
On Tue, Jan 20, 2026 at 04:32:55PM +0530, Prasad Pandit wrote:
> On Fri, 9 Jan 2026 at 18:18, Fabiano Rosas <farosas@suse.de> wrote:
> > The TLS hostname is doing a tour around the world just to be cached
> > into s->hostname. We're already abusing MigrationState by doing that,
> > so incorporate the s->hostname into migration_tls_hostname() and stop
> > passing the string around.
>
> * I get the idea of not passing 's->hostname' around as a parameter, but:
> - migrate_tls_hostname() already returns '->tls_hostname->u.s',
> why are we making it return 's->hostname' too?
> - How are 'tls_hostname->u.s' and 's->hostname' different?
> + virsh(1) migrate has:
> --tls-destination <string> override the destination host name
> used for TLS verification
>
> * IIUC, when --tls-destination is supplied, s->hostname and
> tls_hostname are different, otherwise they are the same? If that is
> the case, could we set tls_hostname = s->hostname when
> params->tls_hostname is not defined below?
Normal default behaviour is that the hostname in the TLS certificate
MUST be validated against the hostname that is specified by the user
(or mgmt app) in the migration URI.
The 'tls-hostname' migration parameter is an optional override that
replaces the hostname from the migration URI, to be used in scenarios
such as:
* The URI is a UNIX socket. eg the UNIX socket points to a proxy
that is transporting data to the dest in some manner. There is
no way to know the hostname from the URI, so 'tls-hostname' must
be provided
* The URI is pointing to a proxy that forwards to the real host.
eg perhaps you setup an SSH tunnel from localhost, to the real
target. QEMU must NOT validate the remote TLS cert against
'localhost', so 'tls-hostname' must be provided by the user
Whatever is usd to validate the TLS hostname, must be data that is
provided by the user in some manner.
TL:DR: always use 'tls-hostname' if it is provided by the user,
otherwise always use the hostname from the migration URI,
otherwise do not provide a hostname.
> ===
> static void migrate_params_test_apply(MigrationParameters *params,
> MigrationParameters *dest)
> {
> if (params->tls_hostname) {
> dest->tls_hostname = QAPI_CLONE(StrOrNull, params->tls_hostname);
> } else {
> /* clear the reference, it's owned by s->parameters */
> dest->tls_hostname = NULL;
> }
> ...
> static void migrate_params_apply(MigrationParameters *params)
> {
> ...
> if (params->tls_hostname) {
> qapi_free_StrOrNull(s->parameters.tls_hostname);
> s->parameters.tls_hostname = QAPI_CLONE(StrOrNull,
> params->tls_hostname);
> }
> ...
> }
> ===
>
> > Reviewed-by: Peter Xu <peterx@redhat.com>
> > Signed-off-by: Fabiano Rosas <farosas@suse.de>
> > ---
> > migration/channel.c | 6 ++----
> > migration/channel.h | 1 -
> > migration/exec.c | 2 +-
> > migration/fd.c | 2 +-
> > migration/file.c | 2 +-
> > migration/multifd.c | 9 +++------
> > migration/options.c | 5 +++++
> > migration/postcopy-ram.c | 2 +-
> > migration/socket.c | 9 +++------
> > migration/tls.c | 17 ++++-------------
> > migration/tls.h | 2 --
> > migration/trace-events | 10 +++++-----
> > 12 files changed, 26 insertions(+), 41 deletions(-)
> >
> > diff --git a/migration/channel.c b/migration/channel.c
> > index b4ab676048..ba14f66d85 100644
> > --- a/migration/channel.c
> > +++ b/migration/channel.c
> > @@ -60,20 +60,18 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> > *
> > * @s: Current migration state
> > * @ioc: Channel to which we are connecting
> > - * @hostname: Where we want to connect
> > * @error: Error indicating failure to connect, free'd here
> > */
> > void migration_channel_connect(MigrationState *s,
> > QIOChannel *ioc,
> > - const char *hostname,
> > Error *error)
> > {
> > trace_migration_set_outgoing_channel(
> > - ioc, object_get_typename(OBJECT(ioc)), hostname, error);
> > + ioc, object_get_typename(OBJECT(ioc)), error);
> >
> > if (!error) {
> > if (migrate_channel_requires_tls_upgrade(ioc)) {
> > - migration_tls_channel_connect(s, ioc, hostname, &error);
> > + migration_tls_channel_connect(s, ioc, &error);
> >
> > if (!error) {
> > /* tls_channel_connect will call back to this
> > diff --git a/migration/channel.h b/migration/channel.h
> > index 5bdb8208a7..2215091323 100644
> > --- a/migration/channel.h
> > +++ b/migration/channel.h
> > @@ -22,7 +22,6 @@ void migration_channel_process_incoming(QIOChannel *ioc);
> >
> > void migration_channel_connect(MigrationState *s,
> > QIOChannel *ioc,
> > - const char *hostname,
> > Error *error_in);
> >
> > int migration_channel_read_peek(QIOChannel *ioc,
> > diff --git a/migration/exec.c b/migration/exec.c
> > index 20e6cccf8c..78fe0fff13 100644
> > --- a/migration/exec.c
> > +++ b/migration/exec.c
> > @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
> > }
> >
> > qio_channel_set_name(ioc, "migration-exec-outgoing");
> > - migration_channel_connect(s, ioc, NULL, NULL);
> > + migration_channel_connect(s, ioc, NULL);
> > object_unref(OBJECT(ioc));
> > }
> >
> > diff --git a/migration/fd.c b/migration/fd.c
> > index 9bf9be6acb..c956b260a4 100644
> > --- a/migration/fd.c
> > +++ b/migration/fd.c
> > @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
> > }
> >
> > qio_channel_set_name(ioc, "migration-fd-outgoing");
> > - migration_channel_connect(s, ioc, NULL, NULL);
> > + migration_channel_connect(s, ioc, NULL);
> > object_unref(OBJECT(ioc));
> > }
> >
> > diff --git a/migration/file.c b/migration/file.c
> > index bb8031e3c7..c490f2b219 100644
> > --- a/migration/file.c
> > +++ b/migration/file.c
> > @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
> > return;
> > }
> > qio_channel_set_name(ioc, "migration-file-outgoing");
> > - migration_channel_connect(s, ioc, NULL, NULL);
> > + migration_channel_connect(s, ioc, NULL);
> > }
> >
> > static gboolean file_accept_incoming_migration(QIOChannel *ioc,
> > diff --git a/migration/multifd.c b/migration/multifd.c
> > index bf6da85af8..3fb1a07ba9 100644
> > --- a/migration/multifd.c
> > +++ b/migration/multifd.c
> > @@ -814,12 +814,10 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
> > QIOChannel *ioc,
> > Error **errp)
> > {
> > - MigrationState *s = migrate_get_current();
> > - const char *hostname = s->hostname;
> > MultiFDTLSThreadArgs *args;
> > QIOChannelTLS *tioc;
> >
> > - tioc = migration_tls_client_create(ioc, hostname, errp);
> > + tioc = migration_tls_client_create(ioc, errp);
> > if (!tioc) {
> > return false;
> > }
> > @@ -829,7 +827,7 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
> > * created TLS channel, which has already taken a reference.
> > */
> > object_unref(OBJECT(ioc));
> > - trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
> > + trace_multifd_tls_outgoing_handshake_start(ioc, tioc);
> > qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
> >
> > args = g_new0(MultiFDTLSThreadArgs, 1);
> > @@ -876,8 +874,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
> > goto out;
> > }
> >
> > - trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)),
> > - migrate_get_current()->hostname);
> > + trace_multifd_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
> >
> > if (migrate_channel_requires_tls_upgrade(ioc)) {
> > ret = multifd_tls_channel_connect(p, ioc, &local_err);
> > diff --git a/migration/options.c b/migration/options.c
> > index 9a5a39c886..881034c289 100644
> > --- a/migration/options.c
> > +++ b/migration/options.c
> > @@ -956,6 +956,11 @@ const char *migrate_tls_hostname(void)
> > return s->parameters.tls_hostname->u.s;
> > }
> >
> > + /* hostname saved from a previously connected channel */
> > + if (s->hostname) {
> > + return s->hostname;
> > + }
> > +
>
> * Maybe this return 's->hostname' can be avoided by setting
> tls_hostname = s->hostname at the initialisation stage. If
> 'tls_hostname' and 's->hostname' are different, will the
> migrate_tls_hostname() callers work correctly with s->hostname?
>
> > return NULL;
> > }
> >
> > diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
> > index 98a98138be..7afb42bd27 100644
> > --- a/migration/postcopy-ram.c
> > +++ b/migration/postcopy-ram.c
> > @@ -1966,7 +1966,7 @@ postcopy_preempt_send_channel_new(QIOTask *task, gpointer opaque)
> > }
> >
> > if (migrate_channel_requires_tls_upgrade(ioc)) {
> > - tioc = migration_tls_client_create(ioc, s->hostname, &local_err);
> > + tioc = migration_tls_client_create(ioc, &local_err);
> > if (!tioc) {
> > goto out;
> > }
> > diff --git a/migration/socket.c b/migration/socket.c
> > index 9e379bf56f..426f363b99 100644
> > --- a/migration/socket.c
> > +++ b/migration/socket.c
> > @@ -44,7 +44,6 @@ void socket_send_channel_create(QIOTaskFunc f, void *data)
> >
> > struct SocketConnectData {
> > MigrationState *s;
> > - char *hostname;
> > };
> >
> > static void socket_connect_data_free(void *opaque)
> > @@ -53,7 +52,6 @@ static void socket_connect_data_free(void *opaque)
> > if (!data) {
> > return;
> > }
> > - g_free(data->hostname);
> > g_free(data);
> > }
> >
> > @@ -69,7 +67,7 @@ static void socket_outgoing_migration(QIOTask *task,
> > goto out;
> > }
> >
> > - trace_migration_socket_outgoing_connected(data->hostname);
> > + trace_migration_socket_outgoing_connected();
> >
> > if (migrate_zero_copy_send() &&
> > !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
> > @@ -77,7 +75,7 @@ static void socket_outgoing_migration(QIOTask *task,
> > }
> >
> > out:
> > - migration_channel_connect(data->s, sioc, data->hostname, err);
> > + migration_channel_connect(data->s, sioc, err);
> > object_unref(OBJECT(sioc));
> > }
> >
> > @@ -96,7 +94,7 @@ void socket_start_outgoing_migration(MigrationState *s,
> > outgoing_args.saddr = addr;
> >
> > if (saddr->type == SOCKET_ADDRESS_TYPE_INET) {
> > - data->hostname = g_strdup(saddr->u.inet.host);
> > + s->hostname = g_strdup(saddr->u.inet.host);
> > }
> >
> > qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-outgoing");
> > @@ -180,4 +178,3 @@ void socket_start_incoming_migration(SocketAddress *saddr,
> > qapi_free_SocketAddress(address);
> > }
> > }
> > -
> > diff --git a/migration/tls.c b/migration/tls.c
> > index 1df31bdcbb..82f58cbc78 100644
> > --- a/migration/tls.c
> > +++ b/migration/tls.c
> > @@ -112,12 +112,11 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
> > } else {
> > trace_migration_tls_outgoing_handshake_complete();
> > }
> > - migration_channel_connect(s, ioc, NULL, err);
> > + migration_channel_connect(s, ioc, err);
> > object_unref(OBJECT(ioc));
> > }
> >
> > QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> > - const char *hostname,
> > Error **errp)
> > {
> > QCryptoTLSCreds *creds;
> > @@ -127,29 +126,21 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> > return NULL;
> > }
> >
> > - const char *tls_hostname = migrate_tls_hostname();
> > - if (tls_hostname) {
> > - hostname = tls_hostname;
> > - }
> > -
> > - return qio_channel_tls_new_client(ioc, creds, hostname, errp);
> > + return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);
> > }
> >
> > void migration_tls_channel_connect(MigrationState *s,
> > QIOChannel *ioc,
> > - const char *hostname,
> > Error **errp)
> > {
> > QIOChannelTLS *tioc;
> >
> > - tioc = migration_tls_client_create(ioc, hostname, errp);
> > + tioc = migration_tls_client_create(ioc, errp);
> > if (!tioc) {
> > return;
> > }
> >
> > - /* Save hostname into MigrationState for handshake */
> > - s->hostname = g_strdup(hostname);
> > - trace_migration_tls_outgoing_handshake_start(hostname);
> > + trace_migration_tls_outgoing_handshake_start();
> > qio_channel_set_name(QIO_CHANNEL(tioc), "migration-tls-outgoing");
> >
> > if (migrate_postcopy_ram() || migrate_return_path()) {
> > diff --git a/migration/tls.h b/migration/tls.h
> > index 7607cfe803..7cd9c76013 100644
> > --- a/migration/tls.h
> > +++ b/migration/tls.h
> > @@ -27,12 +27,10 @@
> > void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
> >
> > QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> > - const char *hostname,
> > Error **errp);
> >
> > void migration_tls_channel_connect(MigrationState *s,
> > QIOChannel *ioc,
> > - const char *hostname,
> > Error **errp);
> > void migration_tls_channel_end(QIOChannel *ioc, Error **errp);
> > /* Whether the QIO channel requires further TLS handshake? */
> > diff --git a/migration/trace-events b/migration/trace-events
> > index bf11b62b17..da8f909cac 100644
> > --- a/migration/trace-events
> > +++ b/migration/trace-events
> > @@ -149,10 +149,10 @@ multifd_send_sync_main_wait(uint8_t id) "channel %u"
> > multifd_send_terminate_threads(void) ""
> > multifd_send_thread_end(uint8_t id, uint64_t packets) "channel %u packets %" PRIu64
> > multifd_send_thread_start(uint8_t id) "%u"
> > -multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char *hostname) "ioc=%p tioc=%p hostname=%s"
> > +multifd_tls_outgoing_handshake_start(void *ioc, void *tioc) "ioc=%p tioc=%p"
> > multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p err=%s"
> > multifd_tls_outgoing_handshake_complete(void *ioc) "ioc=%p"
> > -multifd_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname) "ioc=%p ioctype=%s hostname=%s"
> > +multifd_set_outgoing_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
> >
> > # migration.c
> > migrate_set_state(const char *new_state) "new state %s"
> > @@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)
> >
> > # channel.c
> > migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
> > -migration_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname, void *err) "ioc=%p ioctype=%s hostname=%s err=%p"
> > +migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err) "ioc=%p ioctype=%s err=%p"
> >
> > # global_state.c
> > migrate_state_too_big(void) ""
> > @@ -328,11 +328,11 @@ migration_file_incoming(const char *filename) "filename=%s"
> >
> > # socket.c
> > migration_socket_incoming_accepted(void) ""
> > -migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
> > +migration_socket_outgoing_connected(void) ""
> > migration_socket_outgoing_error(const char *err) "error=%s"
> >
> > # tls.c
> > -migration_tls_outgoing_handshake_start(const char *hostname) "hostname=%s"
> > +migration_tls_outgoing_handshake_start(void) ""
> > migration_tls_outgoing_handshake_error(const char *err) "err=%s"
> > migration_tls_outgoing_handshake_complete(void) ""
> > migration_tls_incoming_handshake_start(void) ""
> > --
>
> * Otherwise change looks okay.
> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
>
> Thank you.
> ---
> - Prasad
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing
2026-01-20 11:11 ` Daniel P. Berrangé
@ 2026-01-20 11:37 ` Prasad Pandit
2026-01-20 14:51 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:37 UTC (permalink / raw)
To: Daniel P. Berrangé; +Cc: Fabiano Rosas, qemu-devel, peterx
Hi,
On Tue, 20 Jan 2026 at 16:41, Daniel P. Berrangé <berrange@redhat.com> wrote:
> Normal default behaviour is that the hostname in the TLS certificate
> MUST be validated against the hostname that is specified by the user
> (or mgmt app) in the migration URI.
>
> The 'tls-hostname' migration parameter is an optional override that
> replaces the hostname from the migration URI, to be used in scenarios
> such as:
>
> * The URI is a UNIX socket. eg the UNIX socket points to a proxy
> that is transporting data to the dest in some manner. There is
> no way to know the hostname from the URI, so 'tls-hostname' must
> be provided
>
> * The URI is pointing to a proxy that forwards to the real host.
> eg perhaps you setup an SSH tunnel from localhost, to the real
> target. QEMU must NOT validate the remote TLS cert against
> 'localhost', so 'tls-hostname' must be provided by the user
* I see, got it. Thank you for the explanation.
> Whatever is usd to validate the TLS hostname, must be data that is
> provided by the user in some manner.
>
> TL:DR: always use 'tls-hostname' if it is provided by the user,
> otherwise always use the hostname from the migration URI,
> otherwise do not provide a hostname.
* So when 'tls-hostname' is not defined, it could be set to
's->hostname', then migration_tls_hostname() stays unchanged.
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing
2026-01-20 11:37 ` Prasad Pandit
@ 2026-01-20 14:51 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-20 14:51 UTC (permalink / raw)
To: Prasad Pandit, Daniel P. Berrangé; +Cc: qemu-devel, peterx
Prasad Pandit <ppandit@redhat.com> writes:
> Hi,
>
> On Tue, 20 Jan 2026 at 16:41, Daniel P. Berrangé <berrange@redhat.com> wrote:
>> Normal default behaviour is that the hostname in the TLS certificate
>> MUST be validated against the hostname that is specified by the user
>> (or mgmt app) in the migration URI.
>>
>> The 'tls-hostname' migration parameter is an optional override that
>> replaces the hostname from the migration URI, to be used in scenarios
>> such as:
>>
>> * The URI is a UNIX socket. eg the UNIX socket points to a proxy
>> that is transporting data to the dest in some manner. There is
>> no way to know the hostname from the URI, so 'tls-hostname' must
>> be provided
>>
>> * The URI is pointing to a proxy that forwards to the real host.
>> eg perhaps you setup an SSH tunnel from localhost, to the real
>> target. QEMU must NOT validate the remote TLS cert against
>> 'localhost', so 'tls-hostname' must be provided by the user
>
> * I see, got it. Thank you for the explanation.
>
>> Whatever is usd to validate the TLS hostname, must be data that is
>> provided by the user in some manner.
>>
>> TL:DR: always use 'tls-hostname' if it is provided by the user,
>> otherwise always use the hostname from the migration URI,
>> otherwise do not provide a hostname.
>
> * So when 'tls-hostname' is not defined, it could be set to
> 's->hostname', then migration_tls_hostname() stays unchanged.
>
Setting the parameters.tls_hostname would expose the hostname in the
QAPI for the query commands. This is a change in behavior for this
series (and I don't think we'd want it either).
options.c contains the "internal API" that exposes the migration options
to the rest of the code. If there's somewhere to change the hostname
seen by the rest of the code, it's there.
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 05/25] migration: Move postcopy_try_recover into migration_incoming_process
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (3 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 04/25] migration: Cleanup TLS handshake hostname passing Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 11:38 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer Fabiano Rosas
` (19 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
The postcopy_try_recover() call doesn't need to be duplicated, move it
into migration_incoming_process().
This removes code from migration_fd_process_incoming() so it can be
removed in the near future.
(the diff is a bit strange because migration_incoming_process() was
moved after postcopy_try_recover())
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index c45393f40e..4af5baad59 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -943,12 +943,6 @@ static void migration_incoming_setup(QEMUFile *f)
qemu_file_set_blocking(f, false, &error_abort);
}
-void migration_incoming_process(void)
-{
- Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, NULL);
- qemu_coroutine_enter(co);
-}
-
/* Returns true if recovered from a paused migration, otherwise false */
static bool postcopy_try_recover(void)
{
@@ -982,12 +976,19 @@ static bool postcopy_try_recover(void)
return false;
}
+void migration_incoming_process(void)
+{
+ if (postcopy_try_recover()) {
+ return;
+ }
+
+ Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, NULL);
+ qemu_coroutine_enter(co);
+}
+
void migration_fd_process_incoming(QEMUFile *f)
{
migration_incoming_setup(f);
- if (postcopy_try_recover()) {
- return;
- }
migration_incoming_process();
}
@@ -1087,10 +1088,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
}
if (migration_has_main_and_multifd_channels()) {
- /* If it's a recovery, we're done */
- if (postcopy_try_recover()) {
- return;
- }
migration_incoming_process();
}
}
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 05/25] migration: Move postcopy_try_recover into migration_incoming_process
2026-01-09 12:40 ` [PATCH v3 05/25] migration: Move postcopy_try_recover into migration_incoming_process Fabiano Rosas
@ 2026-01-19 11:38 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 11:38 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
> (the diff is a bit strange because migration_incoming_process() was
> moved after postcopy_try_recover())
* This note could be removed from the commit message.
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 23 ++++++++++-------------
> 1 file changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index c45393f40e..4af5baad59 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -943,12 +943,6 @@ static void migration_incoming_setup(QEMUFile *f)
> qemu_file_set_blocking(f, false, &error_abort);
> }
>
> -void migration_incoming_process(void)
> -{
> - Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, NULL);
> - qemu_coroutine_enter(co);
> -}
> -
> /* Returns true if recovered from a paused migration, otherwise false */
> static bool postcopy_try_recover(void)
> {
> @@ -982,12 +976,19 @@ static bool postcopy_try_recover(void)
> return false;
> }
>
> +void migration_incoming_process(void)
> +{
> + if (postcopy_try_recover()) {
> + return;
> + }
> +
> + Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, NULL);
> + qemu_coroutine_enter(co);
> +}
> +
> void migration_fd_process_incoming(QEMUFile *f)
> {
> migration_incoming_setup(f);
> - if (postcopy_try_recover()) {
> - return;
> - }
> migration_incoming_process();
> }
>
> @@ -1087,10 +1088,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> }
>
> if (migration_has_main_and_multifd_channels()) {
> - /* If it's a recovery, we're done */
> - if (postcopy_try_recover()) {
> - return;
> - }
> migration_incoming_process();
> }
> }
> --
* Looks right.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (4 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 05/25] migration: Move postcopy_try_recover into migration_incoming_process Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:06 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 07/25] migration: Free the error earlier in the resume case Fabiano Rosas
` (18 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Mark Kanda, Ben Chaney
cpr_set_incoming_mode() is only called on the target side, so
migrate_mode() on the source side is the same as s->parameters.mode.
Use the function to reduce explicit access to s->parameters, we have
options.c for that.
Cc: Mark Kanda <mark.kanda@oracle.com>
Cc: Ben Chaney <bchaney@akamai.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/cpr-exec.c | 2 +-
migration/migration.c | 27 +++++++++++++--------------
migration/migration.h | 5 ++---
3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/migration/cpr-exec.c b/migration/cpr-exec.c
index da287d8031..e315a30f92 100644
--- a/migration/cpr-exec.c
+++ b/migration/cpr-exec.c
@@ -164,7 +164,7 @@ static void cpr_exec_cb(void *opaque)
err = NULL;
/* Note, we can go from state COMPLETED to FAILED */
- migration_call_notifiers(s, MIG_EVENT_PRECOPY_FAILED, NULL);
+ migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
if (!migration_block_activate(&err)) {
/* error was already reported */
diff --git a/migration/migration.c b/migration/migration.c
index 4af5baad59..388e0be5a2 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1534,7 +1534,7 @@ static void migration_cleanup(MigrationState *s)
}
type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
MIG_EVENT_PRECOPY_DONE;
- migration_call_notifiers(s, type, NULL);
+ migration_call_notifiers(type, NULL);
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
}
@@ -1696,10 +1696,9 @@ void migration_remove_notifier(NotifierWithReturn *notify)
}
}
-int migration_call_notifiers(MigrationState *s, MigrationEventType type,
- Error **errp)
+int migration_call_notifiers(MigrationEventType type, Error **errp)
{
- MigMode mode = s->parameters.mode;
+ MigMode mode = migrate_mode();
MigrationEvent e;
NotifierWithReturn *notifier;
GSList *elem, *next;
@@ -1780,9 +1779,9 @@ bool migration_thread_is_self(void)
return qemu_thread_is_self(&s->thread);
}
-bool migrate_mode_is_cpr(MigrationState *s)
+bool migrate_mode_is_cpr(void)
{
- MigMode mode = s->parameters.mode;
+ MigMode mode = migrate_mode();
return mode == MIG_MODE_CPR_REBOOT ||
mode == MIG_MODE_CPR_TRANSFER ||
mode == MIG_MODE_CPR_EXEC;
@@ -2136,7 +2135,7 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
}
}
- if (migrate_mode_is_cpr(s)) {
+ if (migrate_mode_is_cpr()) {
const char *conflict = NULL;
if (migrate_postcopy()) {
@@ -2252,7 +2251,7 @@ void qmp_migrate(const char *uri, bool has_channels,
return;
}
- if (s->parameters.mode == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
+ if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
error_setg(errp, "missing 'cpr' migration channel");
return;
}
@@ -2277,7 +2276,7 @@ void qmp_migrate(const char *uri, bool has_channels,
* in which case the target will not listen for the incoming migration
* connection, so qmp_migrate_finish will fail to connect, and then recover.
*/
- if (s->parameters.mode == MIG_MODE_CPR_TRANSFER) {
+ if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
QAPI_CLONE(MigrationAddress, addr));
@@ -2852,7 +2851,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
* at the transition to postcopy and after the device state; in particular
* spice needs to trigger a transition now
*/
- migration_call_notifiers(ms, MIG_EVENT_PRECOPY_DONE, NULL);
+ migration_call_notifiers(MIG_EVENT_PRECOPY_DONE, NULL);
migration_downtime_end(ms);
@@ -2901,7 +2900,7 @@ fail:
migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
}
migration_block_activate(NULL);
- migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
+ migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
bql_unlock();
return -1;
}
@@ -3003,7 +3002,7 @@ static int migration_completion_precopy(MigrationState *s)
bql_lock();
- if (!migrate_mode_is_cpr(s)) {
+ if (!migrate_mode_is_cpr()) {
ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
if (ret < 0) {
goto out_unlock;
@@ -4049,7 +4048,7 @@ void migration_connect(MigrationState *s, Error *error_in)
rate_limit = migrate_max_bandwidth();
/* Notify before starting migration thread */
- if (migration_call_notifiers(s, MIG_EVENT_PRECOPY_SETUP, &local_err)) {
+ if (migration_call_notifiers(MIG_EVENT_PRECOPY_SETUP, &local_err)) {
goto fail;
}
}
@@ -4085,7 +4084,7 @@ void migration_connect(MigrationState *s, Error *error_in)
return;
}
- if (migrate_mode_is_cpr(s)) {
+ if (migrate_mode_is_cpr()) {
ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
if (ret < 0) {
error_setg(&local_err, "migration_stop_vm failed, error %d", -ret);
diff --git a/migration/migration.h b/migration/migration.h
index ccc4e536a5..8b55d4741a 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -538,8 +538,7 @@ bool migrate_has_error(MigrationState *s);
void migration_connect(MigrationState *s, Error *error_in);
-int migration_call_notifiers(MigrationState *s, MigrationEventType type,
- Error **errp);
+int migration_call_notifiers(MigrationEventType type, Error **errp);
int migrate_init(MigrationState *s, Error **errp);
bool migration_is_blocked(Error **errp);
@@ -548,7 +547,7 @@ bool migration_in_postcopy(void);
bool migration_postcopy_is_alive(MigrationStatus state);
MigrationState *migrate_get_current(void);
bool migration_has_failed(MigrationState *);
-bool migrate_mode_is_cpr(MigrationState *);
+bool migrate_mode_is_cpr(void);
uint64_t ram_get_total_transferred_pages(void);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer
2026-01-09 12:40 ` [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer Fabiano Rosas
@ 2026-01-19 12:06 ` Prasad Pandit
2026-01-20 17:52 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:06 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Mark Kanda, Ben Chaney
Hi,
On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
> cpr_set_incoming_mode() is only called on the target side, so
> migrate_mode() on the source side is the same as s->parameters.mode.
* This message is a little confusing, as the connection between
cpr_set_incoming_mode() and migrate_mode() is not evident. IIUC,
during CPR migration mode is not set explicitly on the source side, so
cpr_get_incoming_mode() returns none, so migrate_mode() sets it to
s->parameters.mode and returns it. Ideally it should be set to
s->parameters.mode. /* I wonder why we need such differention between
incoming and outgoing modes. */
> Use the function to reduce explicit access to s->parameters, we have
> options.c for that.
>
> Cc: Mark Kanda <mark.kanda@oracle.com>
> Cc: Ben Chaney <bchaney@akamai.com>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/cpr-exec.c | 2 +-
> migration/migration.c | 27 +++++++++++++--------------
> migration/migration.h | 5 ++---
> 3 files changed, 16 insertions(+), 18 deletions(-)
>
> diff --git a/migration/cpr-exec.c b/migration/cpr-exec.c
> index da287d8031..e315a30f92 100644
> --- a/migration/cpr-exec.c
> +++ b/migration/cpr-exec.c
> @@ -164,7 +164,7 @@ static void cpr_exec_cb(void *opaque)
> err = NULL;
>
> /* Note, we can go from state COMPLETED to FAILED */
/* Going from COMPLETED -> FAILED says something not right here,
maybe we are prematurely moving to COMPLETED state. */
> - migration_call_notifiers(s, MIG_EVENT_PRECOPY_FAILED, NULL);
> + migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
>
> if (!migration_block_activate(&err)) {
> /* error was already reported */
> diff --git a/migration/migration.c b/migration/migration.c
> index 4af5baad59..388e0be5a2 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1534,7 +1534,7 @@ static void migration_cleanup(MigrationState *s)
> }
> type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
> MIG_EVENT_PRECOPY_DONE;
> - migration_call_notifiers(s, type, NULL);
> + migration_call_notifiers(type, NULL);
> yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> }
>
> @@ -1696,10 +1696,9 @@ void migration_remove_notifier(NotifierWithReturn *notify)
> }
> }
>
> -int migration_call_notifiers(MigrationState *s, MigrationEventType type,
> - Error **errp)
> +int migration_call_notifiers(MigrationEventType type, Error **errp)
> {
> - MigMode mode = s->parameters.mode;
> + MigMode mode = migrate_mode();
> MigrationEvent e;
> NotifierWithReturn *notifier;
> GSList *elem, *next;
> @@ -1780,9 +1779,9 @@ bool migration_thread_is_self(void)
> return qemu_thread_is_self(&s->thread);
> }
>
> -bool migrate_mode_is_cpr(MigrationState *s)
> +bool migrate_mode_is_cpr(void)
> {
> - MigMode mode = s->parameters.mode;
> + MigMode mode = migrate_mode();
> return mode == MIG_MODE_CPR_REBOOT ||
> mode == MIG_MODE_CPR_TRANSFER ||
> mode == MIG_MODE_CPR_EXEC;
> @@ -2136,7 +2135,7 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
> }
> }
>
> - if (migrate_mode_is_cpr(s)) {
> + if (migrate_mode_is_cpr()) {
> const char *conflict = NULL;
>
> if (migrate_postcopy()) {
> @@ -2252,7 +2251,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> return;
> }
>
> - if (s->parameters.mode == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
> error_setg(errp, "missing 'cpr' migration channel");
> return;
> }
> @@ -2277,7 +2276,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> * in which case the target will not listen for the incoming migration
> * connection, so qmp_migrate_finish will fail to connect, and then recover.
> */
> - if (s->parameters.mode == MIG_MODE_CPR_TRANSFER) {
> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
* Shouldn't we use migrate_mode_is_cpr() to avoid this comparison?
> migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
> QAPI_CLONE(MigrationAddress, addr));
>
> @@ -2852,7 +2851,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
> * at the transition to postcopy and after the device state; in particular
> * spice needs to trigger a transition now
> */
> - migration_call_notifiers(ms, MIG_EVENT_PRECOPY_DONE, NULL);
> + migration_call_notifiers(MIG_EVENT_PRECOPY_DONE, NULL);
>
> migration_downtime_end(ms);
>
> @@ -2901,7 +2900,7 @@ fail:
> migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
> }
> migration_block_activate(NULL);
> - migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
> + migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
> bql_unlock();
> return -1;
> }
> @@ -3003,7 +3002,7 @@ static int migration_completion_precopy(MigrationState *s)
>
> bql_lock();
>
> - if (!migrate_mode_is_cpr(s)) {
> + if (!migrate_mode_is_cpr()) {
> ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
> if (ret < 0) {
> goto out_unlock;
> @@ -4049,7 +4048,7 @@ void migration_connect(MigrationState *s, Error *error_in)
> rate_limit = migrate_max_bandwidth();
>
> /* Notify before starting migration thread */
> - if (migration_call_notifiers(s, MIG_EVENT_PRECOPY_SETUP, &local_err)) {
> + if (migration_call_notifiers(MIG_EVENT_PRECOPY_SETUP, &local_err)) {
> goto fail;
> }
> }
> @@ -4085,7 +4084,7 @@ void migration_connect(MigrationState *s, Error *error_in)
> return;
> }
>
> - if (migrate_mode_is_cpr(s)) {
> + if (migrate_mode_is_cpr()) {
> ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
> if (ret < 0) {
> error_setg(&local_err, "migration_stop_vm failed, error %d", -ret);
> diff --git a/migration/migration.h b/migration/migration.h
> index ccc4e536a5..8b55d4741a 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -538,8 +538,7 @@ bool migrate_has_error(MigrationState *s);
>
> void migration_connect(MigrationState *s, Error *error_in);
>
> -int migration_call_notifiers(MigrationState *s, MigrationEventType type,
> - Error **errp);
> +int migration_call_notifiers(MigrationEventType type, Error **errp);
>
> int migrate_init(MigrationState *s, Error **errp);
> bool migration_is_blocked(Error **errp);
> @@ -548,7 +547,7 @@ bool migration_in_postcopy(void);
> bool migration_postcopy_is_alive(MigrationStatus state);
> MigrationState *migrate_get_current(void);
> bool migration_has_failed(MigrationState *);
> -bool migrate_mode_is_cpr(MigrationState *);
> +bool migrate_mode_is_cpr(void);
>
> uint64_t ram_get_total_transferred_pages(void);
>
> --
* Otherwise change looks okay. Needs minor fix above.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer
2026-01-19 12:06 ` Prasad Pandit
@ 2026-01-20 17:52 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-20 17:52 UTC (permalink / raw)
To: Prasad Pandit; +Cc: qemu-devel, peterx, berrange, Mark Kanda, Ben Chaney
Prasad Pandit <ppandit@redhat.com> writes:
> Hi,
>
> On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
>> cpr_set_incoming_mode() is only called on the target side, so
>> migrate_mode() on the source side is the same as s->parameters.mode.
>
> * This message is a little confusing, as the connection between
> cpr_set_incoming_mode() and migrate_mode() is not evident. IIUC,
> during CPR migration mode is not set explicitly on the source side, so
> cpr_get_incoming_mode() returns none, so migrate_mode() sets it to
> s->parameters.mode and returns it. Ideally it should be set to
> s->parameters.mode. /* I wonder why we need such differention between
> incoming and outgoing modes. */
>
Good question. I had to go check. It's subtle and not properly
documented: cpr_state_load() is called before current_migration
exists. There is no parameters.mode at that point.
>> Use the function to reduce explicit access to s->parameters, we have
>> options.c for that.
>>
>> Cc: Mark Kanda <mark.kanda@oracle.com>
>> Cc: Ben Chaney <bchaney@akamai.com>
>> Reviewed-by: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>> ---
>> migration/cpr-exec.c | 2 +-
>> migration/migration.c | 27 +++++++++++++--------------
>> migration/migration.h | 5 ++---
>> 3 files changed, 16 insertions(+), 18 deletions(-)
>>
>> diff --git a/migration/cpr-exec.c b/migration/cpr-exec.c
>> index da287d8031..e315a30f92 100644
>> --- a/migration/cpr-exec.c
>> +++ b/migration/cpr-exec.c
>> @@ -164,7 +164,7 @@ static void cpr_exec_cb(void *opaque)
>> err = NULL;
>>
>> /* Note, we can go from state COMPLETED to FAILED */
>
> /* Going from COMPLETED -> FAILED says something not right here,
> maybe we are prematurely moving to COMPLETED state. */
>
I agree there's a dissonance, but there is no "after" to counterpart
this "prematurely".
cpr-exec happens after migration completes, it needs to receive the
MIG_EVENT_PRECOPY_DONE completion notifier. But then there's a slight
chance that the execvp() may fail.
If it fails, then migration is naturally FAILED and the
MIG_EVENT_PRECOPY_FAILED notifiers are called below.
If it succeeds, then it's another process image, s->state is no more.
There might also be considerations from the management layer side in
seeing the completion event and from the device migration code in seeing
the completion notifier, I'm not sure.
>> - migration_call_notifiers(s, MIG_EVENT_PRECOPY_FAILED, NULL);
>> + migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
>>
>> if (!migration_block_activate(&err)) {
>> /* error was already reported */
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 4af5baad59..388e0be5a2 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -1534,7 +1534,7 @@ static void migration_cleanup(MigrationState *s)
>> }
>> type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
>> MIG_EVENT_PRECOPY_DONE;
>> - migration_call_notifiers(s, type, NULL);
>> + migration_call_notifiers(type, NULL);
>> yank_unregister_instance(MIGRATION_YANK_INSTANCE);
>> }
>>
>> @@ -1696,10 +1696,9 @@ void migration_remove_notifier(NotifierWithReturn *notify)
>> }
>> }
>>
>> -int migration_call_notifiers(MigrationState *s, MigrationEventType type,
>> - Error **errp)
>> +int migration_call_notifiers(MigrationEventType type, Error **errp)
>> {
>> - MigMode mode = s->parameters.mode;
>> + MigMode mode = migrate_mode();
>> MigrationEvent e;
>> NotifierWithReturn *notifier;
>> GSList *elem, *next;
>> @@ -1780,9 +1779,9 @@ bool migration_thread_is_self(void)
>> return qemu_thread_is_self(&s->thread);
>> }
>>
>> -bool migrate_mode_is_cpr(MigrationState *s)
>> +bool migrate_mode_is_cpr(void)
>> {
>> - MigMode mode = s->parameters.mode;
>> + MigMode mode = migrate_mode();
>> return mode == MIG_MODE_CPR_REBOOT ||
>> mode == MIG_MODE_CPR_TRANSFER ||
>> mode == MIG_MODE_CPR_EXEC;
>> @@ -2136,7 +2135,7 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
>> }
>> }
>>
>> - if (migrate_mode_is_cpr(s)) {
>> + if (migrate_mode_is_cpr()) {
>> const char *conflict = NULL;
>>
>> if (migrate_postcopy()) {
>> @@ -2252,7 +2251,7 @@ void qmp_migrate(const char *uri, bool has_channels,
>> return;
>> }
>>
>> - if (s->parameters.mode == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
>> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
>> error_setg(errp, "missing 'cpr' migration channel");
>> return;
>> }
>> @@ -2277,7 +2276,7 @@ void qmp_migrate(const char *uri, bool has_channels,
>> * in which case the target will not listen for the incoming migration
>> * connection, so qmp_migrate_finish will fail to connect, and then recover.
>> */
>> - if (s->parameters.mode == MIG_MODE_CPR_TRANSFER) {
>> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
>
> * Shouldn't we use migrate_mode_is_cpr() to avoid this comparison?
>
There are other CPR modes that I don't think we want to match here, only
cpr-transfer.
>> migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
>> QAPI_CLONE(MigrationAddress, addr));
>>
>> @@ -2852,7 +2851,7 @@ static int postcopy_start(MigrationState *ms, Error **errp)
>> * at the transition to postcopy and after the device state; in particular
>> * spice needs to trigger a transition now
>> */
>> - migration_call_notifiers(ms, MIG_EVENT_PRECOPY_DONE, NULL);
>> + migration_call_notifiers(MIG_EVENT_PRECOPY_DONE, NULL);
>>
>> migration_downtime_end(ms);
>>
>> @@ -2901,7 +2900,7 @@ fail:
>> migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
>> }
>> migration_block_activate(NULL);
>> - migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
>> + migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);
>> bql_unlock();
>> return -1;
>> }
>> @@ -3003,7 +3002,7 @@ static int migration_completion_precopy(MigrationState *s)
>>
>> bql_lock();
>>
>> - if (!migrate_mode_is_cpr(s)) {
>> + if (!migrate_mode_is_cpr()) {
>> ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
>> if (ret < 0) {
>> goto out_unlock;
>> @@ -4049,7 +4048,7 @@ void migration_connect(MigrationState *s, Error *error_in)
>> rate_limit = migrate_max_bandwidth();
>>
>> /* Notify before starting migration thread */
>> - if (migration_call_notifiers(s, MIG_EVENT_PRECOPY_SETUP, &local_err)) {
>> + if (migration_call_notifiers(MIG_EVENT_PRECOPY_SETUP, &local_err)) {
>> goto fail;
>> }
>> }
>> @@ -4085,7 +4084,7 @@ void migration_connect(MigrationState *s, Error *error_in)
>> return;
>> }
>>
>> - if (migrate_mode_is_cpr(s)) {
>> + if (migrate_mode_is_cpr()) {
>> ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
>> if (ret < 0) {
>> error_setg(&local_err, "migration_stop_vm failed, error %d", -ret);
>> diff --git a/migration/migration.h b/migration/migration.h
>> index ccc4e536a5..8b55d4741a 100644
>> --- a/migration/migration.h
>> +++ b/migration/migration.h
>> @@ -538,8 +538,7 @@ bool migrate_has_error(MigrationState *s);
>>
>> void migration_connect(MigrationState *s, Error *error_in);
>>
>> -int migration_call_notifiers(MigrationState *s, MigrationEventType type,
>> - Error **errp);
>> +int migration_call_notifiers(MigrationEventType type, Error **errp);
>>
>> int migrate_init(MigrationState *s, Error **errp);
>> bool migration_is_blocked(Error **errp);
>> @@ -548,7 +547,7 @@ bool migration_in_postcopy(void);
>> bool migration_postcopy_is_alive(MigrationStatus state);
>> MigrationState *migrate_get_current(void);
>> bool migration_has_failed(MigrationState *);
>> -bool migrate_mode_is_cpr(MigrationState *);
>> +bool migrate_mode_is_cpr(void);
>>
>> uint64_t ram_get_total_transferred_pages(void);
>>
>> --
>
> * Otherwise change looks okay. Needs minor fix above.
> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
>
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 07/25] migration: Free the error earlier in the resume case
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (5 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 06/25] migration: Use migrate_mode() to query for cpr-transfer Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-15 11:54 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 08/25] migration: Move error reporting out of migration_cleanup Fabiano Rosas
` (17 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Freeing the error at migration_connect() is redundant in the normal
migration case. The freeing already happened at migrate_init():
qmp_migrate()
-> migrate_prepare()
-> migrate_init()
-> qmp_migrate_finish()
-> *_start_outgoing_migration()
-> migration_channel_connect()
-> migration_connect()
For the resume case, migrate_prepare() returns early and doesn't reach
migrate_init(). Move the extra migrate_error_free() call to
migrate_prepare() along with the resume check.
Also change migrate_init() to use migrate_error_free(), so it's easier
to see where are the places the error gets freed.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 388e0be5a2..9204029c88 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1811,8 +1811,8 @@ int migrate_init(MigrationState *s, Error **errp)
s->setup_time = 0;
s->start_postcopy = false;
s->migration_thread_running = false;
- error_free(s->error);
- s->error = NULL;
+
+ migrate_error_free(s);
if (should_send_vmdesc()) {
s->vmdesc = json_writer_new(false);
@@ -2087,6 +2087,13 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_PAUSED,
MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
+ /*
+ * If there's a previous error, free it and prepare for
+ * another one. For the non-resume case, this happens at
+ * migrate_init() below.
+ */
+ migrate_error_free(s);
+
/* This is a resume, skip init status */
return true;
}
@@ -4015,13 +4022,6 @@ void migration_connect(MigrationState *s, Error *error_in)
bool resume = (s->state == MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
int ret;
- /*
- * If there's a previous error, free it and prepare for another one.
- * Meanwhile if migration completes successfully, there won't have an error
- * dumped when calling migration_cleanup().
- */
- migrate_error_free(s);
-
s->expected_downtime = migrate_downtime_limit();
if (error_in) {
migration_connect_error_propagate(s, error_in);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 07/25] migration: Free the error earlier in the resume case
2026-01-09 12:40 ` [PATCH v3 07/25] migration: Free the error earlier in the resume case Fabiano Rosas
@ 2026-01-15 11:54 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-15 11:54 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1811,8 +1811,8 @@ int migrate_init(MigrationState *s, Error **errp)
> s->setup_time = 0;
> s->start_postcopy = false;
> s->migration_thread_running = false;
> - error_free(s->error);
> - s->error = NULL;
> +
> + migrate_error_free(s);
>
> if (should_send_vmdesc()) {
> s->vmdesc = json_writer_new(false);
> @@ -2087,6 +2087,13 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
> migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_PAUSED,
> MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
>
> + /*
> + * If there's a previous error, free it and prepare for
> + * another one. For the non-resume case, this happens at
> + * migrate_init() below.
> + */
> + migrate_error_free(s);
> +
> /* This is a resume, skip init status */
> return true;
> }
> @@ -4015,13 +4022,6 @@ void migration_connect(MigrationState *s, Error *error_in)
> bool resume = (s->state == MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
> int ret;
>
> - /*
> - * If there's a previous error, free it and prepare for another one.
> - * Meanwhile if migration completes successfully, there won't have an error
> - * dumped when calling migration_cleanup().
> - */
> - migrate_error_free(s);
> -
> s->expected_downtime = migrate_downtime_limit();
> if (error_in) {
> migration_connect_error_propagate(s, error_in);
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 08/25] migration: Move error reporting out of migration_cleanup
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (6 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 07/25] migration: Free the error earlier in the resume case Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:32 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 09/25] migration: Expand migration_connect_error_propagate to cover cancelling Fabiano Rosas
` (16 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
In the next patches migration_cleanup() will be used in qmp_migrate(),
which currently does not show an error message. Move the error
reporting out of migration_cleanup() to avoid duplicated messages.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 9204029c88..7bef787f00 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1528,10 +1528,6 @@ static void migration_cleanup(MigrationState *s)
MIGRATION_STATUS_CANCELLED);
}
- if (s->error) {
- /* It is used on info migrate. We can't free it */
- error_report_err(error_copy(s->error));
- }
type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
MIG_EVENT_PRECOPY_DONE;
migration_call_notifiers(type, NULL);
@@ -1540,7 +1536,12 @@ static void migration_cleanup(MigrationState *s)
static void migration_cleanup_bh(void *opaque)
{
- migration_cleanup(opaque);
+ MigrationState *s = opaque;
+
+ migration_cleanup(s);
+ if (s->error) {
+ error_report_err(error_copy(s->error));
+ }
}
/*
@@ -4025,18 +4026,12 @@ void migration_connect(MigrationState *s, Error *error_in)
s->expected_downtime = migrate_downtime_limit();
if (error_in) {
migration_connect_error_propagate(s, error_in);
- if (resume) {
- /*
- * Don't do cleanup for resume if channel is invalid, but only dump
- * the error. We wait for another channel connect from the user.
- * The error_report still gives HMP user a hint on what failed.
- * It's normally done in migration_cleanup(), but call it here
- * explicitly.
- */
- error_report_err(error_copy(s->error));
- } else {
+ if (!resume) {
migration_cleanup(s);
}
+ if (s->error) {
+ error_report_err(error_copy(s->error));
+ }
return;
}
@@ -4115,8 +4110,10 @@ fail:
if (s->state != MIGRATION_STATUS_CANCELLING) {
migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
}
- error_report_err(local_err);
migration_cleanup(s);
+ if (s->error) {
+ error_report_err(error_copy(s->error));
+ }
}
static void migration_class_init(ObjectClass *klass, const void *data)
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 08/25] migration: Move error reporting out of migration_cleanup
2026-01-09 12:40 ` [PATCH v3 08/25] migration: Move error reporting out of migration_cleanup Fabiano Rosas
@ 2026-01-19 12:32 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:32 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> In the next patches migration_cleanup() will be used in qmp_migrate(),
> which currently does not show an error message. Move the error
> reporting out of migration_cleanup() to avoid duplicated messages.
* duplicated -> duplicate OR double
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 29 +++++++++++++----------------
> 1 file changed, 13 insertions(+), 16 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 9204029c88..7bef787f00 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1528,10 +1528,6 @@ static void migration_cleanup(MigrationState *s)
> MIGRATION_STATUS_CANCELLED);
> }
>
> - if (s->error) {
> - /* It is used on info migrate. We can't free it */
> - error_report_err(error_copy(s->error));
> - }
> type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
> MIG_EVENT_PRECOPY_DONE;
> migration_call_notifiers(type, NULL);
> @@ -1540,7 +1536,12 @@ static void migration_cleanup(MigrationState *s)
>
> static void migration_cleanup_bh(void *opaque)
> {
> - migration_cleanup(opaque);
> + MigrationState *s = opaque;
> +
> + migration_cleanup(s);
> + if (s->error) {
> + error_report_err(error_copy(s->error));
> + }
> }
>
> /*
> @@ -4025,18 +4026,12 @@ void migration_connect(MigrationState *s, Error *error_in)
> s->expected_downtime = migrate_downtime_limit();
> if (error_in) {
> migration_connect_error_propagate(s, error_in);
> - if (resume) {
> - /*
> - * Don't do cleanup for resume if channel is invalid, but only dump
> - * the error. We wait for another channel connect from the user.
> - * The error_report still gives HMP user a hint on what failed.
> - * It's normally done in migration_cleanup(), but call it here
> - * explicitly.
> - */
> - error_report_err(error_copy(s->error));
> - } else {
> + if (!resume) {
> migration_cleanup(s);
> }
> + if (s->error) {
> + error_report_err(error_copy(s->error));
> + }
> return;
> }
>
> @@ -4115,8 +4110,10 @@ fail:
> if (s->state != MIGRATION_STATUS_CANCELLING) {
> migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
> }
> - error_report_err(local_err);
> migration_cleanup(s);
> + if (s->error) {
> + error_report_err(error_copy(s->error));
> + }
> }
>
> static void migration_class_init(ObjectClass *klass, const void *data)
> --
* Change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 09/25] migration: Expand migration_connect_error_propagate to cover cancelling
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (7 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 08/25] migration: Move error reporting out of migration_cleanup Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 9:15 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 10/25] migration: yank: Move register instance earlier Fabiano Rosas
` (15 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Cover the CANCELLING state in migration_connect_error_propagate() and
use it to funnel errors from migrate_prepare() until the end of
migration_connect().
(add some line breaks for legibility)
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 7bef787f00..259b60af04 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1575,18 +1575,25 @@ static void migrate_error_free(MigrationState *s)
static void migration_connect_error_propagate(MigrationState *s, Error *error)
{
MigrationStatus current = s->state;
- MigrationStatus next;
-
- assert(s->to_dst_file == NULL);
+ MigrationStatus next = MIGRATION_STATUS_NONE;
switch (current) {
case MIGRATION_STATUS_SETUP:
next = MIGRATION_STATUS_FAILED;
break;
+
case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
/* Never fail a postcopy migration; switch back to PAUSED instead */
next = MIGRATION_STATUS_POSTCOPY_PAUSED;
break;
+
+ case MIGRATION_STATUS_CANCELLING:
+ /*
+ * Don't move out of CANCELLING, the only valid transition is to
+ * CANCELLED, at migration_cleanup().
+ */
+ break;
+
default:
/*
* This really shouldn't happen. Just be careful to not crash a VM
@@ -1597,7 +1604,10 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
return;
}
- migrate_set_state(&s->state, current, next);
+ if (next) {
+ migrate_set_state(&s->state, current, next);
+ }
+
migrate_error_propagate(s, error);
}
@@ -4106,10 +4116,7 @@ void migration_connect(MigrationState *s, Error *error_in)
return;
fail:
- migrate_error_propagate(s, error_copy(local_err));
- if (s->state != MIGRATION_STATUS_CANCELLING) {
- migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
- }
+ migration_connect_error_propagate(s, local_err);
migration_cleanup(s);
if (s->error) {
error_report_err(error_copy(s->error));
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 09/25] migration: Expand migration_connect_error_propagate to cover cancelling
2026-01-09 12:40 ` [PATCH v3 09/25] migration: Expand migration_connect_error_propagate to cover cancelling Fabiano Rosas
@ 2026-01-20 9:15 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 9:15 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> (add some line breaks for legibility)
* This note could be expunged. It's only helpful for reviews.
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 23 +++++++++++++++--------
> 1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 7bef787f00..259b60af04 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1575,18 +1575,25 @@ static void migrate_error_free(MigrationState *s)
> static void migration_connect_error_propagate(MigrationState *s, Error *error)
> {
> MigrationStatus current = s->state;
> - MigrationStatus next;
> -
> - assert(s->to_dst_file == NULL);
> + MigrationStatus next = MIGRATION_STATUS_NONE;
>
> switch (current) {
> case MIGRATION_STATUS_SETUP:
> next = MIGRATION_STATUS_FAILED;
> break;
> +
> case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
> /* Never fail a postcopy migration; switch back to PAUSED instead */
> next = MIGRATION_STATUS_POSTCOPY_PAUSED;
> break;
> +
> + case MIGRATION_STATUS_CANCELLING:
> + /*
> + * Don't move out of CANCELLING, the only valid transition is to
> + * CANCELLED, at migration_cleanup().
> + */
> + break;
> +
> default:
> /*
> * This really shouldn't happen. Just be careful to not crash a VM
> @@ -1597,7 +1604,10 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
> return;
> }
>
> - migrate_set_state(&s->state, current, next);
> + if (next) {
> + migrate_set_state(&s->state, current, next);
> + }
> +
> migrate_error_propagate(s, error);
> }
>
> @@ -4106,10 +4116,7 @@ void migration_connect(MigrationState *s, Error *error_in)
> return;
>
> fail:
> - migrate_error_propagate(s, error_copy(local_err));
> - if (s->state != MIGRATION_STATUS_CANCELLING) {
> - migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
> - }
> + migration_connect_error_propagate(s, local_err);
> migration_cleanup(s);
> if (s->error) {
> error_report_err(error_copy(s->error));
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 10/25] migration: yank: Move register instance earlier
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (8 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 09/25] migration: Expand migration_connect_error_propagate to cover cancelling Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 9:01 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 11/25] migration: Fold migration_cleanup() into migration_connect_error_propagate() Fabiano Rosas
` (14 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Move the register_instance call to migrate_prepare() so it can be
paired with the unregister_instance at migration_cleanup(). Otherwise,
the cleanup cannot be run when cpr_state_save() fails because the
instance is registered only after it.
When resuming from a paused postcopy migration, migrate_prepare()
returns early, but migration_cleanup() doesn't run, so the yank will
remain paired.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 259b60af04..164cb26c48 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2180,11 +2180,12 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
return false;
}
+ yank_register_instance(MIGRATION_YANK_INSTANCE, &error_abort);
+
return true;
}
-static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
- Error **errp);
+static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
void *opaque)
@@ -2209,7 +2210,7 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
{
MigrationAddress *addr = opaque;
- qmp_migrate_finish(addr, false, NULL);
+ qmp_migrate_finish(addr, NULL);
cpr_state_close();
migrate_hup_delete(migrate_get_current());
@@ -2221,7 +2222,6 @@ void qmp_migrate(const char *uri, bool has_channels,
MigrationChannelList *channels, bool has_detach, bool detach,
bool has_resume, bool resume, Error **errp)
{
- bool resume_requested;
Error *local_err = NULL;
MigrationState *s = migrate_get_current();
g_autoptr(MigrationChannel) channel = NULL;
@@ -2274,8 +2274,7 @@ void qmp_migrate(const char *uri, bool has_channels,
return;
}
- resume_requested = has_resume && resume;
- if (!migrate_prepare(s, resume_requested, errp)) {
+ if (!migrate_prepare(s, has_resume && resume, errp)) {
/* Error detected, put into errp */
return;
}
@@ -2299,28 +2298,22 @@ void qmp_migrate(const char *uri, bool has_channels,
QAPI_CLONE(MigrationAddress, addr));
} else {
- qmp_migrate_finish(addr, resume_requested, errp);
+ qmp_migrate_finish(addr, errp);
}
out:
if (local_err) {
+ yank_unregister_instance(MIGRATION_YANK_INSTANCE);
migration_connect_error_propagate(s, error_copy(local_err));
error_propagate(errp, local_err);
}
}
-static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
- Error **errp)
+static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
{
MigrationState *s = migrate_get_current();
Error *local_err = NULL;
- if (!resume_requested) {
- if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
- return;
- }
- }
-
if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
SocketAddress *saddr = &addr->u.socket;
if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
@@ -2343,9 +2336,6 @@ static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
}
if (local_err) {
- if (!resume_requested) {
- yank_unregister_instance(MIGRATION_YANK_INSTANCE);
- }
migration_connect_error_propagate(s, error_copy(local_err));
error_propagate(errp, local_err);
return;
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 10/25] migration: yank: Move register instance earlier
2026-01-09 12:40 ` [PATCH v3 10/25] migration: yank: Move register instance earlier Fabiano Rosas
@ 2026-01-20 9:01 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 9:01 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> Move the register_instance call to migrate_prepare() so it can be
> paired with the unregister_instance at migration_cleanup(). Otherwise,
> the cleanup cannot be run when cpr_state_save() fails because the
> instance is registered only after it.
>
> When resuming from a paused postcopy migration, migrate_prepare()
> returns early, but migration_cleanup() doesn't run, so the yank will
> remain paired.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 26 ++++++++------------------
> 1 file changed, 8 insertions(+), 18 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 259b60af04..164cb26c48 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2180,11 +2180,12 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
> return false;
> }
>
> + yank_register_instance(MIGRATION_YANK_INSTANCE, &error_abort);
> +
> return true;
> }
>
> -static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
> - Error **errp);
> +static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
>
> static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
> void *opaque)
> @@ -2209,7 +2210,7 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> {
> MigrationAddress *addr = opaque;
>
> - qmp_migrate_finish(addr, false, NULL);
> + qmp_migrate_finish(addr, NULL);
>
> cpr_state_close();
> migrate_hup_delete(migrate_get_current());
> @@ -2221,7 +2222,6 @@ void qmp_migrate(const char *uri, bool has_channels,
> MigrationChannelList *channels, bool has_detach, bool detach,
> bool has_resume, bool resume, Error **errp)
> {
> - bool resume_requested;
> Error *local_err = NULL;
> MigrationState *s = migrate_get_current();
> g_autoptr(MigrationChannel) channel = NULL;
> @@ -2274,8 +2274,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> return;
> }
>
> - resume_requested = has_resume && resume;
> - if (!migrate_prepare(s, resume_requested, errp)) {
> + if (!migrate_prepare(s, has_resume && resume, errp)) {
> /* Error detected, put into errp */
> return;
> }
> @@ -2299,28 +2298,22 @@ void qmp_migrate(const char *uri, bool has_channels,
> QAPI_CLONE(MigrationAddress, addr));
>
> } else {
> - qmp_migrate_finish(addr, resume_requested, errp);
> + qmp_migrate_finish(addr, errp);
> }
>
> out:
> if (local_err) {
> + yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> migration_connect_error_propagate(s, error_copy(local_err));
> error_propagate(errp, local_err);
> }
> }
>
> -static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
> - Error **errp)
> +static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
> {
> MigrationState *s = migrate_get_current();
> Error *local_err = NULL;
>
> - if (!resume_requested) {
> - if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
> - return;
> - }
> - }
> -
> if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
> SocketAddress *saddr = &addr->u.socket;
> if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
> @@ -2343,9 +2336,6 @@ static void qmp_migrate_finish(MigrationAddress *addr, bool resume_requested,
> }
>
> if (local_err) {
> - if (!resume_requested) {
> - yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> - }
> migration_connect_error_propagate(s, error_copy(local_err));
> error_propagate(errp, local_err);
> return;
> --
* Looks good.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 11/25] migration: Fold migration_cleanup() into migration_connect_error_propagate()
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (9 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 10/25] migration: yank: Move register instance earlier Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-16 12:25 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 12/25] migration: Handle error in the early async paths Fabiano Rosas
` (13 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Whenever an error occurs between migrate_init() and the start of
migration_thread, do cleanup immediately after.
This allows the special casing for resume to be removed from
migration_connect(), that check is now done at
migration_connect_error_propagate() which already had a case for
resume.
The cleanup at qmp_migrate_finish_cb can also be removed because it
will always be reached wither via the error path at
qmp_migrate_finish->migration_connect_error_propagate or via the
migrate_cleanup_bh.
The yank_unregister_instance at qmp_migrate() is now replaced by the
one at migration_cleanup().
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 164cb26c48..d57cc2dc3b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1576,15 +1576,21 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
{
MigrationStatus current = s->state;
MigrationStatus next = MIGRATION_STATUS_NONE;
+ bool resume = false;
switch (current) {
case MIGRATION_STATUS_SETUP:
next = MIGRATION_STATUS_FAILED;
break;
+ case MIGRATION_STATUS_POSTCOPY_PAUSED:
+ resume = true;
+ break;
+
case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
/* Never fail a postcopy migration; switch back to PAUSED instead */
next = MIGRATION_STATUS_POSTCOPY_PAUSED;
+ resume = true;
break;
case MIGRATION_STATUS_CANCELLING:
@@ -1609,6 +1615,10 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
}
migrate_error_propagate(s, error);
+
+ if (!resume) {
+ migration_cleanup(s);
+ }
}
void migration_cancel(void)
@@ -2211,9 +2221,6 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
MigrationAddress *addr = opaque;
qmp_migrate_finish(addr, NULL);
-
- cpr_state_close();
- migrate_hup_delete(migrate_get_current());
qapi_free_MigrationAddress(addr);
return G_SOURCE_REMOVE;
}
@@ -2222,7 +2229,6 @@ void qmp_migrate(const char *uri, bool has_channels,
MigrationChannelList *channels, bool has_detach, bool detach,
bool has_resume, bool resume, Error **errp)
{
- Error *local_err = NULL;
MigrationState *s = migrate_get_current();
g_autoptr(MigrationChannel) channel = NULL;
MigrationAddress *addr = NULL;
@@ -2279,6 +2285,13 @@ void qmp_migrate(const char *uri, bool has_channels,
return;
}
+ /*
+ * The migrate_prepare() above calls migrate_init(). From this
+ * point on, until the end of migration, make sure any failures
+ * eventually result in a call to migration_cleanup().
+ */
+ Error *local_err = NULL;
+
if (!cpr_state_save(cpr_channel, &local_err)) {
goto out;
}
@@ -2303,7 +2316,6 @@ void qmp_migrate(const char *uri, bool has_channels,
out:
if (local_err) {
- yank_unregister_instance(MIGRATION_YANK_INSTANCE);
migration_connect_error_propagate(s, error_copy(local_err));
error_propagate(errp, local_err);
}
@@ -4026,9 +4038,6 @@ void migration_connect(MigrationState *s, Error *error_in)
s->expected_downtime = migrate_downtime_limit();
if (error_in) {
migration_connect_error_propagate(s, error_in);
- if (!resume) {
- migration_cleanup(s);
- }
if (s->error) {
error_report_err(error_copy(s->error));
}
@@ -4107,7 +4116,6 @@ void migration_connect(MigrationState *s, Error *error_in)
fail:
migration_connect_error_propagate(s, local_err);
- migration_cleanup(s);
if (s->error) {
error_report_err(error_copy(s->error));
}
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 11/25] migration: Fold migration_cleanup() into migration_connect_error_propagate()
2026-01-09 12:40 ` [PATCH v3 11/25] migration: Fold migration_cleanup() into migration_connect_error_propagate() Fabiano Rosas
@ 2026-01-16 12:25 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-16 12:25 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
> Whenever an error occurs between migrate_init() and the start of
> migration_thread, do cleanup immediately after.
* .. immediately after -> immediately.
> The cleanup at qmp_migrate_finish_cb can also be removed because it
> will always be reached wither via the error path at
* wither -> whether OR either
> qmp_migrate_finish->migration_connect_error_propagate or via the
> migrate_cleanup_bh.
>
> The yank_unregister_instance at qmp_migrate() is now replaced by the
> one at migration_cleanup().
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 26 +++++++++++++++++---------
> 1 file changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 164cb26c48..d57cc2dc3b 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1576,15 +1576,21 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
> {
> MigrationStatus current = s->state;
> MigrationStatus next = MIGRATION_STATUS_NONE;
> + bool resume = false;
>
> switch (current) {
> case MIGRATION_STATUS_SETUP:
> next = MIGRATION_STATUS_FAILED;
> break;
>
> + case MIGRATION_STATUS_POSTCOPY_PAUSED:
> + resume = true;
> + break;
> +
> case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
> /* Never fail a postcopy migration; switch back to PAUSED instead */
> next = MIGRATION_STATUS_POSTCOPY_PAUSED;
> + resume = true;
> break;
>
> case MIGRATION_STATUS_CANCELLING:
> @@ -1609,6 +1615,10 @@ static void migration_connect_error_propagate(MigrationState *s, Error *error)
> }
>
> migrate_error_propagate(s, error);
> +
> + if (!resume) {
> + migration_cleanup(s);
> + }
> }
>
> void migration_cancel(void)
> @@ -2211,9 +2221,6 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> MigrationAddress *addr = opaque;
>
> qmp_migrate_finish(addr, NULL);
> -
> - cpr_state_close();
> - migrate_hup_delete(migrate_get_current());
> qapi_free_MigrationAddress(addr);
> return G_SOURCE_REMOVE;
> }
> @@ -2222,7 +2229,6 @@ void qmp_migrate(const char *uri, bool has_channels,
> MigrationChannelList *channels, bool has_detach, bool detach,
> bool has_resume, bool resume, Error **errp)
> {
> - Error *local_err = NULL;
> MigrationState *s = migrate_get_current();
> g_autoptr(MigrationChannel) channel = NULL;
> MigrationAddress *addr = NULL;
> @@ -2279,6 +2285,13 @@ void qmp_migrate(const char *uri, bool has_channels,
> return;
> }
>
> + /*
> + * The migrate_prepare() above calls migrate_init(). From this
> + * point on, until the end of migration, make sure any failures
> + * eventually result in a call to migration_cleanup().
> + */
* +1
> + Error *local_err = NULL;
> +
> if (!cpr_state_save(cpr_channel, &local_err)) {
> goto out;
> }
> @@ -2303,7 +2316,6 @@ void qmp_migrate(const char *uri, bool has_channels,
>
> out:
> if (local_err) {
> - yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> migration_connect_error_propagate(s, error_copy(local_err));
> error_propagate(errp, local_err);
> }
> @@ -4026,9 +4038,6 @@ void migration_connect(MigrationState *s, Error *error_in)
> s->expected_downtime = migrate_downtime_limit();
> if (error_in) {
> migration_connect_error_propagate(s, error_in);
> - if (!resume) {
> - migration_cleanup(s);
> - }
> if (s->error) {
> error_report_err(error_copy(s->error));
> }
> @@ -4107,7 +4116,6 @@ void migration_connect(MigrationState *s, Error *error_in)
>
> fail:
> migration_connect_error_propagate(s, local_err);
> - migration_cleanup(s);
> if (s->error) {
> error_report_err(error_copy(s->error));
> }
> --
> 2.51.0
* Change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 12/25] migration: Handle error in the early async paths
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (10 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 11/25] migration: Fold migration_cleanup() into migration_connect_error_propagate() Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-16 11:17 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup Fabiano Rosas
` (12 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Li Zhijian
Simplify migration_channel_connect() and migration_connect() to not
take an error as input. Move the error handling into the paths that
generate the error.
To achieve this, call migration_connect_error_propagate() from
socket.c and tls.c, which are the async paths.
For the sync paths, the handling is done as normal by returning all
the way to qmp_migrate_finish(), except that now the sync paths don't
pass the error forward into migration_connect() anymore.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 49 ++++++++++++++++++++----------------------
migration/channel.h | 4 +---
migration/exec.c | 2 +-
migration/fd.c | 2 +-
migration/file.c | 2 +-
migration/migration.c | 11 ++--------
migration/migration.h | 3 ++-
migration/rdma.c | 2 +-
migration/socket.c | 17 ++++++++-------
migration/tls.c | 14 ++++++------
migration/tls.h | 3 +--
migration/trace-events | 2 +-
12 files changed, 50 insertions(+), 61 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index ba14f66d85..26cb7bf059 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -60,38 +60,35 @@ void migration_channel_process_incoming(QIOChannel *ioc)
*
* @s: Current migration state
* @ioc: Channel to which we are connecting
- * @error: Error indicating failure to connect, free'd here
*/
-void migration_channel_connect(MigrationState *s,
- QIOChannel *ioc,
- Error *error)
+void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
{
- trace_migration_set_outgoing_channel(
- ioc, object_get_typename(OBJECT(ioc)), error);
+ trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
- if (!error) {
- if (migrate_channel_requires_tls_upgrade(ioc)) {
- migration_tls_channel_connect(s, ioc, &error);
+ if (migrate_channel_requires_tls_upgrade(ioc)) {
+ Error *local_err = NULL;
- if (!error) {
- /* tls_channel_connect will call back to this
- * function after the TLS handshake,
- * so we mustn't call migration_connect until then
- */
-
- return;
- }
- } else {
- QEMUFile *f = qemu_file_new_output(ioc);
-
- migration_ioc_register_yank(ioc);
-
- qemu_mutex_lock(&s->qemu_file_lock);
- s->to_dst_file = f;
- qemu_mutex_unlock(&s->qemu_file_lock);
+ migration_tls_channel_connect(s, ioc, &local_err);
+ if (local_err) {
+ migration_connect_error_propagate(s, local_err);
}
+
+ /*
+ * async: the above will call back to this function after
+ * the TLS handshake is successfully completed.
+ */
+ return;
}
- migration_connect(s, error);
+
+ QEMUFile *f = qemu_file_new_output(ioc);
+
+ migration_ioc_register_yank(ioc);
+
+ qemu_mutex_lock(&s->qemu_file_lock);
+ s->to_dst_file = f;
+ qemu_mutex_unlock(&s->qemu_file_lock);
+
+ migration_connect(s);
}
diff --git a/migration/channel.h b/migration/channel.h
index 2215091323..ccfeaaef18 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -20,9 +20,7 @@
void migration_channel_process_incoming(QIOChannel *ioc);
-void migration_channel_connect(MigrationState *s,
- QIOChannel *ioc,
- Error *error_in);
+void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
int migration_channel_read_peek(QIOChannel *ioc,
const char *buf,
diff --git a/migration/exec.c b/migration/exec.c
index 78fe0fff13..d83a07435a 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
}
qio_channel_set_name(ioc, "migration-exec-outgoing");
- migration_channel_connect(s, ioc, NULL);
+ migration_channel_connect(s, ioc);
object_unref(OBJECT(ioc));
}
diff --git a/migration/fd.c b/migration/fd.c
index c956b260a4..0144a70742 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
}
qio_channel_set_name(ioc, "migration-fd-outgoing");
- migration_channel_connect(s, ioc, NULL);
+ migration_channel_connect(s, ioc);
object_unref(OBJECT(ioc));
}
diff --git a/migration/file.c b/migration/file.c
index c490f2b219..7bb9c1c79f 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
return;
}
qio_channel_set_name(ioc, "migration-file-outgoing");
- migration_channel_connect(s, ioc, NULL);
+ migration_channel_connect(s, ioc);
}
static gboolean file_accept_incoming_migration(QIOChannel *ioc,
diff --git a/migration/migration.c b/migration/migration.c
index d57cc2dc3b..1ea6125454 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1572,7 +1572,7 @@ static void migrate_error_free(MigrationState *s)
}
}
-static void migration_connect_error_propagate(MigrationState *s, Error *error)
+void migration_connect_error_propagate(MigrationState *s, Error *error)
{
MigrationStatus current = s->state;
MigrationStatus next = MIGRATION_STATUS_NONE;
@@ -4028,7 +4028,7 @@ fail_setup:
return NULL;
}
-void migration_connect(MigrationState *s, Error *error_in)
+void migration_connect(MigrationState *s)
{
Error *local_err = NULL;
uint64_t rate_limit;
@@ -4036,13 +4036,6 @@ void migration_connect(MigrationState *s, Error *error_in)
int ret;
s->expected_downtime = migrate_downtime_limit();
- if (error_in) {
- migration_connect_error_propagate(s, error_in);
- if (s->error) {
- error_report_err(error_copy(s->error));
- }
- return;
- }
if (resume) {
/* This is a resumed migration */
diff --git a/migration/migration.h b/migration/migration.h
index 8b55d4741a..d134881eaf 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -533,10 +533,11 @@ void migration_incoming_process(void);
bool migration_has_all_channels(void);
+void migration_connect_error_propagate(MigrationState *s, Error *error);
void migrate_error_propagate(MigrationState *s, Error *error);
bool migrate_has_error(MigrationState *s);
-void migration_connect(MigrationState *s, Error *error_in);
+void migration_connect(MigrationState *s);
int migration_call_notifiers(MigrationEventType type, Error **errp);
diff --git a/migration/rdma.c b/migration/rdma.c
index 337b415889..596a1aba0b 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3997,7 +3997,7 @@ void rdma_start_outgoing_migration(void *opaque,
s->to_dst_file = rdma_new_output(rdma);
s->rdma_migration = true;
- migration_connect(s, NULL);
+ migration_connect(s);
return;
return_path_err:
qemu_rdma_cleanup(rdma);
diff --git a/migration/socket.c b/migration/socket.c
index 426f363b99..298bac30cc 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -59,24 +59,25 @@ static void socket_outgoing_migration(QIOTask *task,
gpointer opaque)
{
struct SocketConnectData *data = opaque;
- QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task));
+ g_autoptr(QIOChannel) sioc = QIO_CHANNEL(qio_task_get_source(task));
Error *err = NULL;
if (qio_task_propagate_error(task, &err)) {
- trace_migration_socket_outgoing_error(error_get_pretty(err));
- goto out;
+ goto err;
}
- trace_migration_socket_outgoing_connected();
-
if (migrate_zero_copy_send() &&
!qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
error_setg(&err, "Zero copy send feature not detected in host kernel");
+ goto err;
}
-out:
- migration_channel_connect(data->s, sioc, err);
- object_unref(OBJECT(sioc));
+ trace_migration_socket_outgoing_connected();
+ migration_channel_connect(data->s, sioc);
+ return;
+err:
+ trace_migration_socket_outgoing_error(error_get_pretty(err));
+ migration_connect_error_propagate(data->s, err);
}
void socket_start_outgoing_migration(MigrationState *s,
diff --git a/migration/tls.c b/migration/tls.c
index 82f58cbc78..837b08294f 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -104,16 +104,17 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
gpointer opaque)
{
MigrationState *s = opaque;
- QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
+ g_autoptr(QIOChannel) ioc = QIO_CHANNEL(qio_task_get_source(task));
Error *err = NULL;
if (qio_task_propagate_error(task, &err)) {
trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));
- } else {
- trace_migration_tls_outgoing_handshake_complete();
+ migration_connect_error_propagate(s, err);
+ return;
}
- migration_channel_connect(s, ioc, err);
- object_unref(OBJECT(ioc));
+
+ trace_migration_tls_outgoing_handshake_complete();
+ migration_channel_connect(s, ioc);
}
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
@@ -129,8 +130,7 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);
}
-void migration_tls_channel_connect(MigrationState *s,
- QIOChannel *ioc,
+void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc,
Error **errp)
{
QIOChannelTLS *tioc;
diff --git a/migration/tls.h b/migration/tls.h
index 7cd9c76013..0e86d38862 100644
--- a/migration/tls.h
+++ b/migration/tls.h
@@ -29,8 +29,7 @@ void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
Error **errp);
-void migration_tls_channel_connect(MigrationState *s,
- QIOChannel *ioc,
+void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc,
Error **errp);
void migration_tls_channel_end(QIOChannel *ioc, Error **errp);
/* Whether the QIO channel requires further TLS handshake? */
diff --git a/migration/trace-events b/migration/trace-events
index da8f909cac..cbf10d0b63 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)
# channel.c
migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
-migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err) "ioc=%p ioctype=%s err=%p"
+migration_set_outgoing_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
# global_state.c
migrate_state_too_big(void) ""
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 12/25] migration: Handle error in the early async paths
2026-01-09 12:40 ` [PATCH v3 12/25] migration: Handle error in the early async paths Fabiano Rosas
@ 2026-01-16 11:17 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-16 11:17 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Li Zhijian
On Fri, 9 Jan 2026 at 18:11, Fabiano Rosas <farosas@suse.de> wrote:
> Simplify migration_channel_connect() and migration_connect() to not
> take an error as input. Move the error handling into the paths that
> generate the error.
>
> To achieve this, call migration_connect_error_propagate() from
> socket.c and tls.c, which are the async paths.
>
> For the sync paths, the handling is done as normal by returning all
> the way to qmp_migrate_finish(), except that now the sync paths don't
> pass the error forward into migration_connect() anymore.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 49 ++++++++++++++++++++----------------------
> migration/channel.h | 4 +---
> migration/exec.c | 2 +-
> migration/fd.c | 2 +-
> migration/file.c | 2 +-
> migration/migration.c | 11 ++--------
> migration/migration.h | 3 ++-
> migration/rdma.c | 2 +-
> migration/socket.c | 17 ++++++++-------
> migration/tls.c | 14 ++++++------
> migration/tls.h | 3 +--
> migration/trace-events | 2 +-
> 12 files changed, 50 insertions(+), 61 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index ba14f66d85..26cb7bf059 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -60,38 +60,35 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> *
> * @s: Current migration state
> * @ioc: Channel to which we are connecting
> - * @error: Error indicating failure to connect, free'd here
> */
> -void migration_channel_connect(MigrationState *s,
> - QIOChannel *ioc,
> - Error *error)
> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
> {
> - trace_migration_set_outgoing_channel(
> - ioc, object_get_typename(OBJECT(ioc)), error);
> + trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
>
> - if (!error) {
> - if (migrate_channel_requires_tls_upgrade(ioc)) {
> - migration_tls_channel_connect(s, ioc, &error);
> + if (migrate_channel_requires_tls_upgrade(ioc)) {
> + Error *local_err = NULL;
>
> - if (!error) {
> - /* tls_channel_connect will call back to this
> - * function after the TLS handshake,
> - * so we mustn't call migration_connect until then
> - */
> -
> - return;
> - }
> - } else {
> - QEMUFile *f = qemu_file_new_output(ioc);
> -
> - migration_ioc_register_yank(ioc);
> -
> - qemu_mutex_lock(&s->qemu_file_lock);
> - s->to_dst_file = f;
> - qemu_mutex_unlock(&s->qemu_file_lock);
> + migration_tls_channel_connect(s, ioc, &local_err);
> + if (local_err) {
> + migration_connect_error_propagate(s, local_err);
> }
> +
> + /*
> + * async: the above will call back to this function after
> + * the TLS handshake is successfully completed.
> + */
> + return;
> }
> - migration_connect(s, error);
> +
> + QEMUFile *f = qemu_file_new_output(ioc);
> +
> + migration_ioc_register_yank(ioc);
> +
> + qemu_mutex_lock(&s->qemu_file_lock);
> + s->to_dst_file = f;
> + qemu_mutex_unlock(&s->qemu_file_lock);
> +
> + migration_connect(s);
> }
>
>
> diff --git a/migration/channel.h b/migration/channel.h
> index 2215091323..ccfeaaef18 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -20,9 +20,7 @@
>
> void migration_channel_process_incoming(QIOChannel *ioc);
>
> -void migration_channel_connect(MigrationState *s,
> - QIOChannel *ioc,
> - Error *error_in);
> +void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
>
> int migration_channel_read_peek(QIOChannel *ioc,
> const char *buf,
> diff --git a/migration/exec.c b/migration/exec.c
> index 78fe0fff13..d83a07435a 100644
> --- a/migration/exec.c
> +++ b/migration/exec.c
> @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
> }
>
> qio_channel_set_name(ioc, "migration-exec-outgoing");
> - migration_channel_connect(s, ioc, NULL);
> + migration_channel_connect(s, ioc);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/fd.c b/migration/fd.c
> index c956b260a4..0144a70742 100644
> --- a/migration/fd.c
> +++ b/migration/fd.c
> @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
> }
>
> qio_channel_set_name(ioc, "migration-fd-outgoing");
> - migration_channel_connect(s, ioc, NULL);
> + migration_channel_connect(s, ioc);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/file.c b/migration/file.c
> index c490f2b219..7bb9c1c79f 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
> return;
> }
> qio_channel_set_name(ioc, "migration-file-outgoing");
> - migration_channel_connect(s, ioc, NULL);
> + migration_channel_connect(s, ioc);
> }
>
> static gboolean file_accept_incoming_migration(QIOChannel *ioc,
> diff --git a/migration/migration.c b/migration/migration.c
> index d57cc2dc3b..1ea6125454 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1572,7 +1572,7 @@ static void migrate_error_free(MigrationState *s)
> }
> }
>
> -static void migration_connect_error_propagate(MigrationState *s, Error *error)
> +void migration_connect_error_propagate(MigrationState *s, Error *error)
> {
> MigrationStatus current = s->state;
> MigrationStatus next = MIGRATION_STATUS_NONE;
> @@ -4028,7 +4028,7 @@ fail_setup:
> return NULL;
> }
>
> -void migration_connect(MigrationState *s, Error *error_in)
> +void migration_connect(MigrationState *s)
> {
> Error *local_err = NULL;
> uint64_t rate_limit;
> @@ -4036,13 +4036,6 @@ void migration_connect(MigrationState *s, Error *error_in)
> int ret;
>
> s->expected_downtime = migrate_downtime_limit();
> - if (error_in) {
> - migration_connect_error_propagate(s, error_in);
> - if (s->error) {
> - error_report_err(error_copy(s->error));
> - }
> - return;
> - }
>
> if (resume) {
> /* This is a resumed migration */
> diff --git a/migration/migration.h b/migration/migration.h
> index 8b55d4741a..d134881eaf 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -533,10 +533,11 @@ void migration_incoming_process(void);
>
> bool migration_has_all_channels(void);
>
> +void migration_connect_error_propagate(MigrationState *s, Error *error);
> void migrate_error_propagate(MigrationState *s, Error *error);
> bool migrate_has_error(MigrationState *s);
>
> -void migration_connect(MigrationState *s, Error *error_in);
> +void migration_connect(MigrationState *s);
>
> int migration_call_notifiers(MigrationEventType type, Error **errp);
>
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 337b415889..596a1aba0b 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -3997,7 +3997,7 @@ void rdma_start_outgoing_migration(void *opaque,
>
> s->to_dst_file = rdma_new_output(rdma);
> s->rdma_migration = true;
> - migration_connect(s, NULL);
> + migration_connect(s);
> return;
> return_path_err:
> qemu_rdma_cleanup(rdma);
> diff --git a/migration/socket.c b/migration/socket.c
> index 426f363b99..298bac30cc 100644
> --- a/migration/socket.c
> +++ b/migration/socket.c
> @@ -59,24 +59,25 @@ static void socket_outgoing_migration(QIOTask *task,
> gpointer opaque)
> {
> struct SocketConnectData *data = opaque;
> - QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task));
> + g_autoptr(QIOChannel) sioc = QIO_CHANNEL(qio_task_get_source(task));
> Error *err = NULL;
>
> if (qio_task_propagate_error(task, &err)) {
> - trace_migration_socket_outgoing_error(error_get_pretty(err));
> - goto out;
> + goto err;
> }
* Goto label and variable both are named the same: 'err'.
> - trace_migration_socket_outgoing_connected();
> -
> if (migrate_zero_copy_send() &&
> !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
> error_setg(&err, "Zero copy send feature not detected in host kernel");
> + goto err;
> }
>
> -out:
> - migration_channel_connect(data->s, sioc, err);
> - object_unref(OBJECT(sioc));
> + trace_migration_socket_outgoing_connected();
> + migration_channel_connect(data->s, sioc);
> + return;
> +err:
> + trace_migration_socket_outgoing_error(error_get_pretty(err));
> + migration_connect_error_propagate(data->s, err);
> }
>
> void socket_start_outgoing_migration(MigrationState *s,
> diff --git a/migration/tls.c b/migration/tls.c
> index 82f58cbc78..837b08294f 100644
> --- a/migration/tls.c
> +++ b/migration/tls.c
> @@ -104,16 +104,17 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
> gpointer opaque)
> {
> MigrationState *s = opaque;
> - QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
> + g_autoptr(QIOChannel) ioc = QIO_CHANNEL(qio_task_get_source(task));
> Error *err = NULL;
>
> if (qio_task_propagate_error(task, &err)) {
> trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));
> - } else {
> - trace_migration_tls_outgoing_handshake_complete();
> + migration_connect_error_propagate(s, err);
> + return;
> }
> - migration_channel_connect(s, ioc, err);
> - object_unref(OBJECT(ioc));
> +
> + trace_migration_tls_outgoing_handshake_complete();
> + migration_channel_connect(s, ioc);
> }
>
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> @@ -129,8 +130,7 @@ QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> return qio_channel_tls_new_client(ioc, creds, migrate_tls_hostname(), errp);
> }
>
> -void migration_tls_channel_connect(MigrationState *s,
> - QIOChannel *ioc,
> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc,
> Error **errp)
> {
> QIOChannelTLS *tioc;
> diff --git a/migration/tls.h b/migration/tls.h
> index 7cd9c76013..0e86d38862 100644
> --- a/migration/tls.h
> +++ b/migration/tls.h
> @@ -29,8 +29,7 @@ void migration_tls_channel_process_incoming(QIOChannel *ioc, Error **errp);
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> Error **errp);
>
> -void migration_tls_channel_connect(MigrationState *s,
> - QIOChannel *ioc,
> +void migration_tls_channel_connect(MigrationState *s, QIOChannel *ioc,
> Error **errp);
> void migration_tls_channel_end(QIOChannel *ioc, Error **errp);
> /* Whether the QIO channel requires further TLS handshake? */
> diff --git a/migration/trace-events b/migration/trace-events
> index da8f909cac..cbf10d0b63 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -204,7 +204,7 @@ migration_transferred_bytes(uint64_t qemu_file, uint64_t multifd, uint64_t rdma)
>
> # channel.c
> migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
> -migration_set_outgoing_channel(void *ioc, const char *ioctype, void *err) "ioc=%p ioctype=%s err=%p"
> +migration_set_outgoing_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
/* /me makes a note to check about this syntax, strings after function
signature. */
> # global_state.c
> migrate_state_too_big(void) ""
> --
> 2.51.0
* Change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (11 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 12/25] migration: Handle error in the early async paths Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:22 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 14/25] migration/rdma: Use common connection paths Fabiano Rosas
` (11 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Centralize, on both sides of migration, the setting of the to_src_file
and from_dst_file QEMUFiles. This will clean up the interface with
channel.c and rdma.c, allowing those files to stop dealing with
QEMUFile themselves.
(multifd_recv_new_channel was changed to return bool+errp for
convenience)
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 9 +----
migration/migration.c | 84 ++++++++++++++++++++++++++-----------------
migration/migration.h | 2 ++
migration/multifd.c | 8 +++--
migration/multifd.h | 2 +-
5 files changed, 61 insertions(+), 44 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index 26cb7bf059..6acce7b2a2 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -14,7 +14,6 @@
#include "channel.h"
#include "tls.h"
#include "migration.h"
-#include "qemu-file.h"
#include "trace.h"
#include "qapi/error.h"
#include "io/channel-tls.h"
@@ -80,14 +79,8 @@ void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
return;
}
- QEMUFile *f = qemu_file_new_output(ioc);
-
migration_ioc_register_yank(ioc);
-
- qemu_mutex_lock(&s->qemu_file_lock);
- s->to_dst_file = f;
- qemu_mutex_unlock(&s->qemu_file_lock);
-
+ migration_outgoing_setup(ioc);
migration_connect(s);
}
diff --git a/migration/migration.c b/migration/migration.c
index 1ea6125454..b7367eb5cf 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -930,17 +930,56 @@ out:
migrate_incoming_unref_outgoing_state();
}
-/**
- * migration_incoming_setup: Setup incoming migration
- * @f: file for main migration channel
+static bool migration_has_main_and_multifd_channels(void);
+
+/*
+ * Returns whether all the necessary channels to proceed with the
+ * incoming migration have been established without error.
*/
-static void migration_incoming_setup(QEMUFile *f)
+bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp)
{
MigrationIncomingState *mis = migration_incoming_get_current();
+ QEMUFile *f;
- assert(!mis->from_src_file);
- mis->from_src_file = f;
- qemu_file_set_blocking(f, false, &error_abort);
+ if (multifd_recv_setup(errp) != 0) {
+ return false;
+ }
+
+ switch (channel) {
+ case CH_MAIN:
+ f = qemu_file_new_input(ioc);
+ assert(!mis->from_src_file);
+ mis->from_src_file = f;
+ qemu_file_set_blocking(f, false, &error_abort);
+ break;
+
+ case CH_MULTIFD:
+ if (!multifd_recv_new_channel(ioc, errp)) {
+ return false;
+ }
+ break;
+
+ case CH_POSTCOPY:
+ assert(!mis->postcopy_qemufile_dst);
+ f = qemu_file_new_input(ioc);
+ postcopy_preempt_new_channel(mis, f);
+ return false;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ return migration_has_main_and_multifd_channels();
+}
+
+void migration_outgoing_setup(QIOChannel *ioc)
+{
+ MigrationState *s = migrate_get_current();
+ QEMUFile *f = qemu_file_new_output(ioc);
+
+ qemu_mutex_lock(&s->qemu_file_lock);
+ s->to_dst_file = f;
+ qemu_mutex_unlock(&s->qemu_file_lock);
}
/* Returns true if recovered from a paused migration, otherwise false */
@@ -988,7 +1027,11 @@ void migration_incoming_process(void)
void migration_fd_process_incoming(QEMUFile *f)
{
- migration_incoming_setup(f);
+ MigrationIncomingState *mis = migration_incoming_get_current();
+
+ assert(!mis->from_src_file);
+ mis->from_src_file = f;
+ qemu_file_set_blocking(f, false, &error_abort);
migration_incoming_process();
}
@@ -1011,8 +1054,6 @@ static bool migration_has_main_and_multifd_channels(void)
void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
{
MigrationIncomingState *mis = migration_incoming_get_current();
- Error *local_err = NULL;
- QEMUFile *f;
uint8_t channel;
uint32_t channel_magic = 0;
int ret = 0;
@@ -1066,28 +1107,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
channel = CH_POSTCOPY;
}
- if (multifd_recv_setup(errp) != 0) {
- return;
- }
-
- if (channel == CH_MAIN) {
- f = qemu_file_new_input(ioc);
- migration_incoming_setup(f);
- } else if (channel == CH_MULTIFD) {
- /* Multiple connections */
- multifd_recv_new_channel(ioc, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- } else if (channel == CH_POSTCOPY) {
- assert(!mis->postcopy_qemufile_dst);
- f = qemu_file_new_input(ioc);
- postcopy_preempt_new_channel(mis, f);
- return;
- }
-
- if (migration_has_main_and_multifd_channels()) {
+ if (migration_incoming_setup(ioc, channel, errp)) {
migration_incoming_process();
}
}
diff --git a/migration/migration.h b/migration/migration.h
index d134881eaf..4dcf299719 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -530,6 +530,8 @@ void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
void migration_fd_process_incoming(QEMUFile *f);
void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
void migration_incoming_process(void);
+bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
+void migration_outgoing_setup(QIOChannel *ioc);
bool migration_has_all_channels(void);
diff --git a/migration/multifd.c b/migration/multifd.c
index 3fb1a07ba9..4980ed4f04 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1521,7 +1521,7 @@ bool multifd_recv_all_channels_created(void)
* Try to receive all multifd channels to get ready for the migration.
* Sets @errp when failing to receive the current channel.
*/
-void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
+bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
{
MultiFDRecvParams *p;
Error *local_err = NULL;
@@ -1536,7 +1536,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
"failed to receive packet"
" via multifd channel %d: ",
qatomic_read(&multifd_recv_state->count));
- return;
+ return false;
}
trace_multifd_recv_new_channel(id);
} else {
@@ -1549,7 +1549,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
id);
multifd_recv_terminate_threads(error_copy(local_err));
error_propagate(errp, local_err);
- return;
+ return false;
}
p->c = ioc;
object_ref(OBJECT(ioc));
@@ -1558,4 +1558,6 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p,
QEMU_THREAD_JOINABLE);
qatomic_inc(&multifd_recv_state->count);
+
+ return true;
}
diff --git a/migration/multifd.h b/migration/multifd.h
index 9b6d81e7ed..89a395aef2 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -42,7 +42,7 @@ int multifd_recv_setup(Error **errp);
void multifd_recv_cleanup(void);
void multifd_recv_shutdown(void);
bool multifd_recv_all_channels_created(void);
-void multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
+bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
void multifd_recv_sync_main(void);
int multifd_send_sync_main(MultiFDSyncReq req);
bool multifd_queue_page(RAMBlock *block, ram_addr_t offset);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup
2026-01-09 12:40 ` [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup Fabiano Rosas
@ 2026-01-19 12:22 ` Prasad Pandit
2026-01-20 18:01 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:22 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
>
> Centralize, on both sides of migration, the setting of the to_src_file
> and from_dst_file QEMUFiles. This will clean up the interface with
> channel.c and rdma.c, allowing those files to stop dealing with
> QEMUFile themselves.
>
> (multifd_recv_new_channel was changed to return bool+errp for
> convenience)
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 9 +----
> migration/migration.c | 84 ++++++++++++++++++++++++++-----------------
> migration/migration.h | 2 ++
> migration/multifd.c | 8 +++--
> migration/multifd.h | 2 +-
> 5 files changed, 61 insertions(+), 44 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 26cb7bf059..6acce7b2a2 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -14,7 +14,6 @@
> #include "channel.h"
> #include "tls.h"
> #include "migration.h"
> -#include "qemu-file.h"
> #include "trace.h"
> #include "qapi/error.h"
> #include "io/channel-tls.h"
> @@ -80,14 +79,8 @@ void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
> return;
> }
>
> - QEMUFile *f = qemu_file_new_output(ioc);
> -
> migration_ioc_register_yank(ioc);
> -
> - qemu_mutex_lock(&s->qemu_file_lock);
> - s->to_dst_file = f;
> - qemu_mutex_unlock(&s->qemu_file_lock);
> -
> + migration_outgoing_setup(ioc);
> migration_connect(s);
> }
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 1ea6125454..b7367eb5cf 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -930,17 +930,56 @@ out:
> migrate_incoming_unref_outgoing_state();
> }
>
> -/**
> - * migration_incoming_setup: Setup incoming migration
> - * @f: file for main migration channel
> +static bool migration_has_main_and_multifd_channels(void);
> +
> +/*
> + * Returns whether all the necessary channels to proceed with the
> + * incoming migration have been established without error.
> */
> -static void migration_incoming_setup(QEMUFile *f)
> +bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> + QEMUFile *f;
>
> - assert(!mis->from_src_file);
> - mis->from_src_file = f;
> - qemu_file_set_blocking(f, false, &error_abort);
> + if (multifd_recv_setup(errp) != 0) {
> + return false;
> + }
> +
> + switch (channel) {
> + case CH_MAIN:
> + f = qemu_file_new_input(ioc);
> + assert(!mis->from_src_file);
> + mis->from_src_file = f;
> + qemu_file_set_blocking(f, false, &error_abort);
> + break;
> +
> + case CH_MULTIFD:
> + if (!multifd_recv_new_channel(ioc, errp)) {
> + return false;
> + }
> + break;
> +
> + case CH_POSTCOPY:
> + assert(!mis->postcopy_qemufile_dst);
> + f = qemu_file_new_input(ioc);
> + postcopy_preempt_new_channel(mis, f);
> + return false;
> +
> + default:
> + g_assert_not_reached();
> + }
> +
> + return migration_has_main_and_multifd_channels();
> +}
> +
> +void migration_outgoing_setup(QIOChannel *ioc)
> +{
> + MigrationState *s = migrate_get_current();
> + QEMUFile *f = qemu_file_new_output(ioc);
> +
> + qemu_mutex_lock(&s->qemu_file_lock);
> + s->to_dst_file = f;
> + qemu_mutex_unlock(&s->qemu_file_lock);
> }
* Shouldn't migration_outgoing_setup() also return bool, to be
consistent with migration_incoming_setup() above? OR make
migration_incoming_setup() return void.
> /* Returns true if recovered from a paused migration, otherwise false */
> @@ -988,7 +1027,11 @@ void migration_incoming_process(void)
>
> void migration_fd_process_incoming(QEMUFile *f)
> {
> - migration_incoming_setup(f);
> + MigrationIncomingState *mis = migration_incoming_get_current();
> +
> + assert(!mis->from_src_file);
> + mis->from_src_file = f;
> + qemu_file_set_blocking(f, false, &error_abort);
> migration_incoming_process();
> }
* Is it possible to move above mis->from_src_file = f part to
migration_incoming_setup()?
> @@ -1011,8 +1054,6 @@ static bool migration_has_main_and_multifd_channels(void)
> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> - Error *local_err = NULL;
> - QEMUFile *f;
> uint8_t channel;
> uint32_t channel_magic = 0;
> int ret = 0;
> @@ -1066,28 +1107,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> channel = CH_POSTCOPY;
> }
>
> - if (multifd_recv_setup(errp) != 0) {
> - return;
> - }
> -
> - if (channel == CH_MAIN) {
> - f = qemu_file_new_input(ioc);
> - migration_incoming_setup(f);
> - } else if (channel == CH_MULTIFD) {
> - /* Multiple connections */
> - multifd_recv_new_channel(ioc, &local_err);
> - if (local_err) {
> - error_propagate(errp, local_err);
> - return;
> - }
> - } else if (channel == CH_POSTCOPY) {
> - assert(!mis->postcopy_qemufile_dst);
> - f = qemu_file_new_input(ioc);
> - postcopy_preempt_new_channel(mis, f);
> - return;
> - }
> -
> - if (migration_has_main_and_multifd_channels()) {
> + if (migration_incoming_setup(ioc, channel, errp)) {
> migration_incoming_process();
> }
> }
> diff --git a/migration/migration.h b/migration/migration.h
> index d134881eaf..4dcf299719 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -530,6 +530,8 @@ void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
> void migration_fd_process_incoming(QEMUFile *f);
> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
> void migration_incoming_process(void);
> +bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
> +void migration_outgoing_setup(QIOChannel *ioc);
>
> bool migration_has_all_channels(void);
>
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 3fb1a07ba9..4980ed4f04 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -1521,7 +1521,7 @@ bool multifd_recv_all_channels_created(void)
> * Try to receive all multifd channels to get ready for the migration.
> * Sets @errp when failing to receive the current channel.
> */
> -void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
> +bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
> {
> MultiFDRecvParams *p;
> Error *local_err = NULL;
> @@ -1536,7 +1536,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
> "failed to receive packet"
> " via multifd channel %d: ",
> qatomic_read(&multifd_recv_state->count));
> - return;
> + return false;
> }
> trace_multifd_recv_new_channel(id);
> } else {
> @@ -1549,7 +1549,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
> id);
> multifd_recv_terminate_threads(error_copy(local_err));
> error_propagate(errp, local_err);
> - return;
> + return false;
> }
> p->c = ioc;
> object_ref(OBJECT(ioc));
> @@ -1558,4 +1558,6 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
> qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p,
> QEMU_THREAD_JOINABLE);
> qatomic_inc(&multifd_recv_state->count);
> +
> + return true;
> }
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 9b6d81e7ed..89a395aef2 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -42,7 +42,7 @@ int multifd_recv_setup(Error **errp);
> void multifd_recv_cleanup(void);
> void multifd_recv_shutdown(void);
> bool multifd_recv_all_channels_created(void);
> -void multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
> +bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
> void multifd_recv_sync_main(void);
> int multifd_send_sync_main(MultiFDSyncReq req);
> bool multifd_queue_page(RAMBlock *block, ram_addr_t offset);
> --
* Change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup
2026-01-19 12:22 ` Prasad Pandit
@ 2026-01-20 18:01 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-20 18:01 UTC (permalink / raw)
To: Prasad Pandit; +Cc: qemu-devel, peterx, berrange
Prasad Pandit <ppandit@redhat.com> writes:
> On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
>>
>> Centralize, on both sides of migration, the setting of the to_src_file
>> and from_dst_file QEMUFiles. This will clean up the interface with
>> channel.c and rdma.c, allowing those files to stop dealing with
>> QEMUFile themselves.
>>
>> (multifd_recv_new_channel was changed to return bool+errp for
>> convenience)
>>
>> Reviewed-by: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>> ---
>> migration/channel.c | 9 +----
>> migration/migration.c | 84 ++++++++++++++++++++++++++-----------------
>> migration/migration.h | 2 ++
>> migration/multifd.c | 8 +++--
>> migration/multifd.h | 2 +-
>> 5 files changed, 61 insertions(+), 44 deletions(-)
>>
>> diff --git a/migration/channel.c b/migration/channel.c
>> index 26cb7bf059..6acce7b2a2 100644
>> --- a/migration/channel.c
>> +++ b/migration/channel.c
>> @@ -14,7 +14,6 @@
>> #include "channel.h"
>> #include "tls.h"
>> #include "migration.h"
>> -#include "qemu-file.h"
>> #include "trace.h"
>> #include "qapi/error.h"
>> #include "io/channel-tls.h"
>> @@ -80,14 +79,8 @@ void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
>> return;
>> }
>>
>> - QEMUFile *f = qemu_file_new_output(ioc);
>> -
>> migration_ioc_register_yank(ioc);
>> -
>> - qemu_mutex_lock(&s->qemu_file_lock);
>> - s->to_dst_file = f;
>> - qemu_mutex_unlock(&s->qemu_file_lock);
>> -
>> + migration_outgoing_setup(ioc);
>> migration_connect(s);
>> }
>>
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 1ea6125454..b7367eb5cf 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -930,17 +930,56 @@ out:
>> migrate_incoming_unref_outgoing_state();
>> }
>>
>> -/**
>> - * migration_incoming_setup: Setup incoming migration
>> - * @f: file for main migration channel
>> +static bool migration_has_main_and_multifd_channels(void);
>> +
>> +/*
>> + * Returns whether all the necessary channels to proceed with the
>> + * incoming migration have been established without error.
>> */
>> -static void migration_incoming_setup(QEMUFile *f)
>> +bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp)
>> {
>> MigrationIncomingState *mis = migration_incoming_get_current();
>> + QEMUFile *f;
>>
>> - assert(!mis->from_src_file);
>> - mis->from_src_file = f;
>> - qemu_file_set_blocking(f, false, &error_abort);
>> + if (multifd_recv_setup(errp) != 0) {
>> + return false;
>> + }
>> +
>> + switch (channel) {
>> + case CH_MAIN:
>> + f = qemu_file_new_input(ioc);
>> + assert(!mis->from_src_file);
>> + mis->from_src_file = f;
>> + qemu_file_set_blocking(f, false, &error_abort);
>> + break;
>> +
>> + case CH_MULTIFD:
>> + if (!multifd_recv_new_channel(ioc, errp)) {
>> + return false;
>> + }
>> + break;
>> +
>> + case CH_POSTCOPY:
>> + assert(!mis->postcopy_qemufile_dst);
>> + f = qemu_file_new_input(ioc);
>> + postcopy_preempt_new_channel(mis, f);
>> + return false;
>> +
>> + default:
>> + g_assert_not_reached();
>> + }
>> +
>> + return migration_has_main_and_multifd_channels();
>> +}
>> +
>> +void migration_outgoing_setup(QIOChannel *ioc)
>> +{
>> + MigrationState *s = migrate_get_current();
>> + QEMUFile *f = qemu_file_new_output(ioc);
>> +
>> + qemu_mutex_lock(&s->qemu_file_lock);
>> + s->to_dst_file = f;
>> + qemu_mutex_unlock(&s->qemu_file_lock);
>> }
>
> * Shouldn't migration_outgoing_setup() also return bool, to be
> consistent with migration_incoming_setup() above? OR make
> migration_incoming_setup() return void.
>
That would be a change simply to make the signatures consistent. It's
not indicative (granted, as it usually is) of a consistency in
design. The reason migration_incoming_setup() returns bool is to follow
the recommendation of returning whether errp is set. Here, there's no
errp, so no need.
(before multifd_send_setup moved to the migration thread, maybe we could
still make both functions more analogous, but I'm not sure how much
benefit that would have brought)
>> /* Returns true if recovered from a paused migration, otherwise false */
>> @@ -988,7 +1027,11 @@ void migration_incoming_process(void)
>>
>> void migration_fd_process_incoming(QEMUFile *f)
>> {
>> - migration_incoming_setup(f);
>> + MigrationIncomingState *mis = migration_incoming_get_current();
>> +
>> + assert(!mis->from_src_file);
>> + mis->from_src_file = f;
>> + qemu_file_set_blocking(f, false, &error_abort);
>> migration_incoming_process();
>> }
>
> * Is it possible to move above mis->from_src_file = f part to
> migration_incoming_setup()?
>
Yes, patch 14.
>
>> @@ -1011,8 +1054,6 @@ static bool migration_has_main_and_multifd_channels(void)
>> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
>> {
>> MigrationIncomingState *mis = migration_incoming_get_current();
>> - Error *local_err = NULL;
>> - QEMUFile *f;
>> uint8_t channel;
>> uint32_t channel_magic = 0;
>> int ret = 0;
>> @@ -1066,28 +1107,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
>> channel = CH_POSTCOPY;
>> }
>>
>> - if (multifd_recv_setup(errp) != 0) {
>> - return;
>> - }
>> -
>> - if (channel == CH_MAIN) {
>> - f = qemu_file_new_input(ioc);
>> - migration_incoming_setup(f);
>> - } else if (channel == CH_MULTIFD) {
>> - /* Multiple connections */
>> - multifd_recv_new_channel(ioc, &local_err);
>> - if (local_err) {
>> - error_propagate(errp, local_err);
>> - return;
>> - }
>> - } else if (channel == CH_POSTCOPY) {
>> - assert(!mis->postcopy_qemufile_dst);
>> - f = qemu_file_new_input(ioc);
>> - postcopy_preempt_new_channel(mis, f);
>> - return;
>> - }
>> -
>> - if (migration_has_main_and_multifd_channels()) {
>> + if (migration_incoming_setup(ioc, channel, errp)) {
>> migration_incoming_process();
>> }
>> }
>> diff --git a/migration/migration.h b/migration/migration.h
>> index d134881eaf..4dcf299719 100644
>> --- a/migration/migration.h
>> +++ b/migration/migration.h
>> @@ -530,6 +530,8 @@ void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
>> void migration_fd_process_incoming(QEMUFile *f);
>> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
>> void migration_incoming_process(void);
>> +bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
>> +void migration_outgoing_setup(QIOChannel *ioc);
>>
>> bool migration_has_all_channels(void);
>>
>> diff --git a/migration/multifd.c b/migration/multifd.c
>> index 3fb1a07ba9..4980ed4f04 100644
>> --- a/migration/multifd.c
>> +++ b/migration/multifd.c
>> @@ -1521,7 +1521,7 @@ bool multifd_recv_all_channels_created(void)
>> * Try to receive all multifd channels to get ready for the migration.
>> * Sets @errp when failing to receive the current channel.
>> */
>> -void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
>> +bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
>> {
>> MultiFDRecvParams *p;
>> Error *local_err = NULL;
>> @@ -1536,7 +1536,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
>> "failed to receive packet"
>> " via multifd channel %d: ",
>> qatomic_read(&multifd_recv_state->count));
>> - return;
>> + return false;
>> }
>> trace_multifd_recv_new_channel(id);
>> } else {
>> @@ -1549,7 +1549,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
>> id);
>> multifd_recv_terminate_threads(error_copy(local_err));
>> error_propagate(errp, local_err);
>> - return;
>> + return false;
>> }
>> p->c = ioc;
>> object_ref(OBJECT(ioc));
>> @@ -1558,4 +1558,6 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
>> qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p,
>> QEMU_THREAD_JOINABLE);
>> qatomic_inc(&multifd_recv_state->count);
>> +
>> + return true;
>> }
>> diff --git a/migration/multifd.h b/migration/multifd.h
>> index 9b6d81e7ed..89a395aef2 100644
>> --- a/migration/multifd.h
>> +++ b/migration/multifd.h
>> @@ -42,7 +42,7 @@ int multifd_recv_setup(Error **errp);
>> void multifd_recv_cleanup(void);
>> void multifd_recv_shutdown(void);
>> bool multifd_recv_all_channels_created(void);
>> -void multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
>> +bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
>> void multifd_recv_sync_main(void);
>> int multifd_send_sync_main(MultiFDSyncReq req);
>> bool multifd_queue_page(RAMBlock *block, ram_addr_t offset);
>> --
>
> * Change looks okay.
> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
>
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 14/25] migration/rdma: Use common connection paths
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (12 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 13/25] migration: Move setting of QEMUFile into migration_outgoing|incoming_setup Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:27 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 15/25] migration: Start incoming from channel.c Fabiano Rosas
` (10 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Li Zhijian
Use the common connection paths for the incoming and outgoing sides of
rdma migration. This removes one usage of QEMUFile from rdma.c. It
also allows further unification of the connection code in next
patches.
Move the channels enum to channel.h so rdma.c can access it. The RDMA
channel is considered a CH_MAIN channel.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.h | 7 +++++++
migration/migration.c | 13 -------------
migration/migration.h | 1 -
migration/rdma.c | 23 +++++++++++------------
4 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/migration/channel.h b/migration/channel.h
index ccfeaaef18..93dedbf52b 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -18,6 +18,13 @@
#include "io/channel.h"
+/* Migration channel types */
+enum {
+ CH_MAIN,
+ CH_MULTIFD,
+ CH_POSTCOPY
+};
+
void migration_channel_process_incoming(QIOChannel *ioc);
void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
diff --git a/migration/migration.c b/migration/migration.c
index b7367eb5cf..7d56d73769 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -91,9 +91,6 @@ enum mig_rp_message_type {
MIG_RP_MSG_MAX
};
-/* Migration channel types */
-enum { CH_MAIN, CH_MULTIFD, CH_POSTCOPY };
-
/* When we add fault tolerance, we could have several
migrations at once. For now we don't need to add
dynamic creation of migration */
@@ -1025,16 +1022,6 @@ void migration_incoming_process(void)
qemu_coroutine_enter(co);
}
-void migration_fd_process_incoming(QEMUFile *f)
-{
- MigrationIncomingState *mis = migration_incoming_get_current();
-
- assert(!mis->from_src_file);
- mis->from_src_file = f;
- qemu_file_set_blocking(f, false, &error_abort);
- migration_incoming_process();
-}
-
static bool migration_has_main_and_multifd_channels(void)
{
MigrationIncomingState *mis = migration_incoming_get_current();
diff --git a/migration/migration.h b/migration/migration.h
index 4dcf299719..cd6cfd62ba 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -527,7 +527,6 @@ struct MigrationState {
void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
MigrationStatus new_state);
-void migration_fd_process_incoming(QEMUFile *f);
void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
void migration_incoming_process(void);
bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
diff --git a/migration/rdma.c b/migration/rdma.c
index 596a1aba0b..d902c8669c 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -15,6 +15,7 @@
*/
#include "qemu/osdep.h"
+#include "channel.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "exec/target_page.h"
@@ -384,7 +385,6 @@ struct QIOChannelRDMA {
QIOChannel parent;
RDMAContext *rdmain;
RDMAContext *rdmaout;
- QEMUFile *file;
bool blocking; /* XXX we don't actually honour this yet */
};
@@ -3836,32 +3836,30 @@ static void qio_channel_rdma_register_types(void)
type_init(qio_channel_rdma_register_types);
-static QEMUFile *rdma_new_input(RDMAContext *rdma)
+static QIOChannel *rdma_new_input(RDMAContext *rdma)
{
QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(object_new(TYPE_QIO_CHANNEL_RDMA));
- rioc->file = qemu_file_new_input(QIO_CHANNEL(rioc));
rioc->rdmain = rdma;
rioc->rdmaout = rdma->return_path;
- return rioc->file;
+ return QIO_CHANNEL(rioc);
}
-static QEMUFile *rdma_new_output(RDMAContext *rdma)
+static QIOChannel *rdma_new_output(RDMAContext *rdma)
{
QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(object_new(TYPE_QIO_CHANNEL_RDMA));
- rioc->file = qemu_file_new_output(QIO_CHANNEL(rioc));
rioc->rdmaout = rdma;
rioc->rdmain = rdma->return_path;
- return rioc->file;
+ return QIO_CHANNEL(rioc);
}
static void rdma_accept_incoming_migration(void *opaque)
{
RDMAContext *rdma = opaque;
- QEMUFile *f;
+ QIOChannel *ioc;
trace_qemu_rdma_accept_incoming_migration();
if (qemu_rdma_accept(rdma) < 0) {
@@ -3875,15 +3873,16 @@ static void rdma_accept_incoming_migration(void *opaque)
return;
}
- f = rdma_new_input(rdma);
- if (f == NULL) {
+ ioc = rdma_new_input(rdma);
+ if (ioc == NULL) {
error_report("RDMA ERROR: could not open RDMA for input");
qemu_rdma_cleanup(rdma);
return;
}
rdma->migration_started_on_destination = 1;
- migration_fd_process_incoming(f);
+ migration_incoming_setup(ioc, CH_MAIN, &error_abort);
+ migration_incoming_process();
}
void rdma_start_incoming_migration(InetSocketAddress *host_port,
@@ -3995,8 +3994,8 @@ void rdma_start_outgoing_migration(void *opaque,
trace_rdma_start_outgoing_migration_after_rdma_connect();
- s->to_dst_file = rdma_new_output(rdma);
s->rdma_migration = true;
+ migration_outgoing_setup(rdma_new_output(rdma));
migration_connect(s);
return;
return_path_err:
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 14/25] migration/rdma: Use common connection paths
2026-01-09 12:40 ` [PATCH v3 14/25] migration/rdma: Use common connection paths Fabiano Rosas
@ 2026-01-19 12:27 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:27 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Li Zhijian
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> Use the common connection paths for the incoming and outgoing sides of
> rdma migration. This removes one usage of QEMUFile from rdma.c. It
> also allows further unification of the connection code in next
> patches.
>
> Move the channels enum to channel.h so rdma.c can access it. The RDMA
> channel is considered a CH_MAIN channel.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.h | 7 +++++++
> migration/migration.c | 13 -------------
> migration/migration.h | 1 -
> migration/rdma.c | 23 +++++++++++------------
> 4 files changed, 18 insertions(+), 26 deletions(-)
>
> diff --git a/migration/channel.h b/migration/channel.h
> index ccfeaaef18..93dedbf52b 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -18,6 +18,13 @@
>
> #include "io/channel.h"
>
> +/* Migration channel types */
> +enum {
> + CH_MAIN,
> + CH_MULTIFD,
> + CH_POSTCOPY
> +};
> +
> void migration_channel_process_incoming(QIOChannel *ioc);
>
> void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
> diff --git a/migration/migration.c b/migration/migration.c
> index b7367eb5cf..7d56d73769 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -91,9 +91,6 @@ enum mig_rp_message_type {
> MIG_RP_MSG_MAX
> };
>
> -/* Migration channel types */
> -enum { CH_MAIN, CH_MULTIFD, CH_POSTCOPY };
> -
> /* When we add fault tolerance, we could have several
> migrations at once. For now we don't need to add
> dynamic creation of migration */
> @@ -1025,16 +1022,6 @@ void migration_incoming_process(void)
> qemu_coroutine_enter(co);
> }
>
> -void migration_fd_process_incoming(QEMUFile *f)
> -{
> - MigrationIncomingState *mis = migration_incoming_get_current();
> -
> - assert(!mis->from_src_file);
> - mis->from_src_file = f;
> - qemu_file_set_blocking(f, false, &error_abort);
> - migration_incoming_process();
> -}
> -
> static bool migration_has_main_and_multifd_channels(void)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> diff --git a/migration/migration.h b/migration/migration.h
> index 4dcf299719..cd6cfd62ba 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -527,7 +527,6 @@ struct MigrationState {
> void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
> MigrationStatus new_state);
>
> -void migration_fd_process_incoming(QEMUFile *f);
> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
> void migration_incoming_process(void);
> bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 596a1aba0b..d902c8669c 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -15,6 +15,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "channel.h"
> #include "qapi/error.h"
> #include "qemu/cutils.h"
> #include "exec/target_page.h"
> @@ -384,7 +385,6 @@ struct QIOChannelRDMA {
> QIOChannel parent;
> RDMAContext *rdmain;
> RDMAContext *rdmaout;
> - QEMUFile *file;
> bool blocking; /* XXX we don't actually honour this yet */
> };
>
> @@ -3836,32 +3836,30 @@ static void qio_channel_rdma_register_types(void)
>
> type_init(qio_channel_rdma_register_types);
>
> -static QEMUFile *rdma_new_input(RDMAContext *rdma)
> +static QIOChannel *rdma_new_input(RDMAContext *rdma)
> {
> QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(object_new(TYPE_QIO_CHANNEL_RDMA));
>
> - rioc->file = qemu_file_new_input(QIO_CHANNEL(rioc));
> rioc->rdmain = rdma;
> rioc->rdmaout = rdma->return_path;
>
> - return rioc->file;
> + return QIO_CHANNEL(rioc);
> }
>
> -static QEMUFile *rdma_new_output(RDMAContext *rdma)
> +static QIOChannel *rdma_new_output(RDMAContext *rdma)
> {
> QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(object_new(TYPE_QIO_CHANNEL_RDMA));
>
> - rioc->file = qemu_file_new_output(QIO_CHANNEL(rioc));
> rioc->rdmaout = rdma;
> rioc->rdmain = rdma->return_path;
>
> - return rioc->file;
> + return QIO_CHANNEL(rioc);
> }
>
> static void rdma_accept_incoming_migration(void *opaque)
> {
> RDMAContext *rdma = opaque;
> - QEMUFile *f;
> + QIOChannel *ioc;
>
> trace_qemu_rdma_accept_incoming_migration();
> if (qemu_rdma_accept(rdma) < 0) {
> @@ -3875,15 +3873,16 @@ static void rdma_accept_incoming_migration(void *opaque)
> return;
> }
>
> - f = rdma_new_input(rdma);
> - if (f == NULL) {
> + ioc = rdma_new_input(rdma);
> + if (ioc == NULL) {
> error_report("RDMA ERROR: could not open RDMA for input");
> qemu_rdma_cleanup(rdma);
> return;
> }
>
> rdma->migration_started_on_destination = 1;
> - migration_fd_process_incoming(f);
> + migration_incoming_setup(ioc, CH_MAIN, &error_abort);
> + migration_incoming_process();
> }
>
> void rdma_start_incoming_migration(InetSocketAddress *host_port,
> @@ -3995,8 +3994,8 @@ void rdma_start_outgoing_migration(void *opaque,
>
> trace_rdma_start_outgoing_migration_after_rdma_connect();
>
> - s->to_dst_file = rdma_new_output(rdma);
> s->rdma_migration = true;
> + migration_outgoing_setup(rdma_new_output(rdma));
> migration_connect(s);
> return;
> return_path_err:
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 15/25] migration: Start incoming from channel.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (13 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 14/25] migration/rdma: Use common connection paths Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 12:24 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 16/25] migration/channel: Rename migration_channel_connect Fabiano Rosas
` (9 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Leave migration_ioc_process_incoming to do only the channel
identification process and move the migration start into
channel.c. Both routines will be renamed in the next patches to better
reflect their usage.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 12 ++++++++++--
migration/channel.h | 5 +++--
migration/migration.c | 13 +++++--------
migration/migration.h | 3 ++-
4 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index 6acce7b2a2..b8d757c17b 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -33,6 +33,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
{
MigrationIncomingState *mis = migration_incoming_get_current();
Error *local_err = NULL;
+ MigChannelType ch;
trace_migration_set_incoming_channel(
ioc, object_get_typename(OBJECT(ioc)));
@@ -41,9 +42,16 @@ void migration_channel_process_incoming(QIOChannel *ioc)
migration_tls_channel_process_incoming(ioc, &local_err);
} else {
migration_ioc_register_yank(ioc);
- migration_ioc_process_incoming(ioc, &local_err);
- }
+ ch = migration_ioc_process_incoming(ioc, &local_err);
+ if (!ch) {
+ goto out;
+ }
+ if (migration_incoming_setup(ioc, ch, &local_err)) {
+ migration_incoming_process();
+ }
+ }
+out:
if (local_err) {
error_report_err(local_err);
migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED);
diff --git a/migration/channel.h b/migration/channel.h
index 93dedbf52b..b361e1c838 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -19,11 +19,12 @@
#include "io/channel.h"
/* Migration channel types */
-enum {
+typedef enum {
+ CH_NONE,
CH_MAIN,
CH_MULTIFD,
CH_POSTCOPY
-};
+} MigChannelType;
void migration_channel_process_incoming(QIOChannel *ioc);
diff --git a/migration/migration.c b/migration/migration.c
index 7d56d73769..a052b99a19 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1038,10 +1038,10 @@ static bool migration_has_main_and_multifd_channels(void)
return true;
}
-void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
+MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
{
MigrationIncomingState *mis = migration_incoming_get_current();
- uint8_t channel;
+ MigChannelType channel = CH_NONE;
uint32_t channel_magic = 0;
int ret = 0;
@@ -1060,7 +1060,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
ret = migration_channel_read_peek(ioc, (void *)&channel_magic,
sizeof(channel_magic), errp);
if (ret != 0) {
- return;
+ goto out;
}
channel_magic = be32_to_cpu(channel_magic);
@@ -1075,7 +1075,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
channel = CH_MAIN;
} else {
error_setg(errp, "unknown channel magic: %u", channel_magic);
- return;
}
} else if (mis->from_src_file && migrate_multifd()) {
/*
@@ -1087,16 +1086,14 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
channel = CH_MAIN;
} else {
error_setg(errp, "non-peekable channel used without multifd");
- return;
}
} else {
assert(migrate_postcopy_preempt());
channel = CH_POSTCOPY;
}
- if (migration_incoming_setup(ioc, channel, errp)) {
- migration_incoming_process();
- }
+out:
+ return channel;
}
/**
diff --git a/migration/migration.h b/migration/migration.h
index cd6cfd62ba..b55cc40613 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -28,6 +28,7 @@
#include "postcopy-ram.h"
#include "system/runstate.h"
#include "migration/misc.h"
+#include "channel.h"
#define MIGRATION_THREAD_SNAPSHOT "mig/snapshot"
#define MIGRATION_THREAD_DIRTY_RATE "mig/dirtyrate"
@@ -527,7 +528,7 @@ struct MigrationState {
void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
MigrationStatus new_state);
-void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
+MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
void migration_incoming_process(void);
bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
void migration_outgoing_setup(QIOChannel *ioc);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 15/25] migration: Start incoming from channel.c
2026-01-09 12:40 ` [PATCH v3 15/25] migration: Start incoming from channel.c Fabiano Rosas
@ 2026-01-19 12:24 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 12:24 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> Leave migration_ioc_process_incoming to do only the channel
> identification process and move the migration start into
> channel.c. Both routines will be renamed in the next patches to better
> reflect their usage.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 12 ++++++++++--
> migration/channel.h | 5 +++--
> migration/migration.c | 13 +++++--------
> migration/migration.h | 3 ++-
> 4 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 6acce7b2a2..b8d757c17b 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -33,6 +33,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> Error *local_err = NULL;
> + MigChannelType ch;
>
> trace_migration_set_incoming_channel(
> ioc, object_get_typename(OBJECT(ioc)));
> @@ -41,9 +42,16 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> migration_tls_channel_process_incoming(ioc, &local_err);
> } else {
> migration_ioc_register_yank(ioc);
> - migration_ioc_process_incoming(ioc, &local_err);
> - }
> + ch = migration_ioc_process_incoming(ioc, &local_err);
> + if (!ch) {
> + goto out;
> + }
>
> + if (migration_incoming_setup(ioc, ch, &local_err)) {
> + migration_incoming_process();
> + }
> + }
> +out:
> if (local_err) {
> error_report_err(local_err);
> migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED);
> diff --git a/migration/channel.h b/migration/channel.h
> index 93dedbf52b..b361e1c838 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -19,11 +19,12 @@
> #include "io/channel.h"
>
> /* Migration channel types */
> -enum {
> +typedef enum {
> + CH_NONE,
> CH_MAIN,
> CH_MULTIFD,
> CH_POSTCOPY
> -};
> +} MigChannelType;
>
> void migration_channel_process_incoming(QIOChannel *ioc);
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 7d56d73769..a052b99a19 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1038,10 +1038,10 @@ static bool migration_has_main_and_multifd_channels(void)
> return true;
> }
>
> -void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> +MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> - uint8_t channel;
> + MigChannelType channel = CH_NONE;
> uint32_t channel_magic = 0;
> int ret = 0;
>
> @@ -1060,7 +1060,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> ret = migration_channel_read_peek(ioc, (void *)&channel_magic,
> sizeof(channel_magic), errp);
> if (ret != 0) {
> - return;
> + goto out;
> }
>
> channel_magic = be32_to_cpu(channel_magic);
> @@ -1075,7 +1075,6 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> channel = CH_MAIN;
> } else {
> error_setg(errp, "unknown channel magic: %u", channel_magic);
> - return;
> }
> } else if (mis->from_src_file && migrate_multifd()) {
> /*
> @@ -1087,16 +1086,14 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
> channel = CH_MAIN;
> } else {
> error_setg(errp, "non-peekable channel used without multifd");
> - return;
> }
> } else {
> assert(migrate_postcopy_preempt());
> channel = CH_POSTCOPY;
> }
>
> - if (migration_incoming_setup(ioc, channel, errp)) {
> - migration_incoming_process();
> - }
> +out:
> + return channel;
> }
>
> /**
> diff --git a/migration/migration.h b/migration/migration.h
> index cd6cfd62ba..b55cc40613 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -28,6 +28,7 @@
> #include "postcopy-ram.h"
> #include "system/runstate.h"
> #include "migration/misc.h"
> +#include "channel.h"
>
> #define MIGRATION_THREAD_SNAPSHOT "mig/snapshot"
> #define MIGRATION_THREAD_DIRTY_RATE "mig/dirtyrate"
> @@ -527,7 +528,7 @@ struct MigrationState {
> void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
> MigrationStatus new_state);
>
> -void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
> +MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
> void migration_incoming_process(void);
> bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
> void migration_outgoing_setup(QIOChannel *ioc);
> --
* Looks right.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 16/25] migration/channel: Rename migration_channel_connect
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (14 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 15/25] migration: Start incoming from channel.c Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:10 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 17/25] migration: Rename instances of start Fabiano Rosas
` (8 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Rename migration_channel_connect to indicate this is the source
side. Future patches will do similar changes to the incoming side and
this will avoid inconsistencies in naming.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 9 +--------
migration/channel.h | 2 +-
migration/exec.c | 2 +-
migration/fd.c | 2 +-
migration/file.c | 2 +-
migration/socket.c | 2 +-
migration/tls.c | 2 +-
7 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index b8d757c17b..f41333adcc 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -61,14 +61,7 @@ out:
}
}
-
-/**
- * @migration_channel_connect - Create new outgoing migration channel
- *
- * @s: Current migration state
- * @ioc: Channel to which we are connecting
- */
-void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
+void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc)
{
trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
diff --git a/migration/channel.h b/migration/channel.h
index b361e1c838..574bfec65c 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -28,7 +28,7 @@ typedef enum {
void migration_channel_process_incoming(QIOChannel *ioc);
-void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
+void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc);
int migration_channel_read_peek(QIOChannel *ioc,
const char *buf,
diff --git a/migration/exec.c b/migration/exec.c
index d83a07435a..d1629944dc 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
}
qio_channel_set_name(ioc, "migration-exec-outgoing");
- migration_channel_connect(s, ioc);
+ migration_channel_connect_outgoing(s, ioc);
object_unref(OBJECT(ioc));
}
diff --git a/migration/fd.c b/migration/fd.c
index 0144a70742..150b236fbf 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
}
qio_channel_set_name(ioc, "migration-fd-outgoing");
- migration_channel_connect(s, ioc);
+ migration_channel_connect_outgoing(s, ioc);
object_unref(OBJECT(ioc));
}
diff --git a/migration/file.c b/migration/file.c
index 7bb9c1c79f..935402f36b 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
return;
}
qio_channel_set_name(ioc, "migration-file-outgoing");
- migration_channel_connect(s, ioc);
+ migration_channel_connect_outgoing(s, ioc);
}
static gboolean file_accept_incoming_migration(QIOChannel *ioc,
diff --git a/migration/socket.c b/migration/socket.c
index 298bac30cc..611915f84d 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -73,7 +73,7 @@ static void socket_outgoing_migration(QIOTask *task,
}
trace_migration_socket_outgoing_connected();
- migration_channel_connect(data->s, sioc);
+ migration_channel_connect_outgoing(data->s, sioc);
return;
err:
trace_migration_socket_outgoing_error(error_get_pretty(err));
diff --git a/migration/tls.c b/migration/tls.c
index 837b08294f..89ba52de02 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -114,7 +114,7 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
}
trace_migration_tls_outgoing_handshake_complete();
- migration_channel_connect(s, ioc);
+ migration_channel_connect_outgoing(s, ioc);
}
QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 16/25] migration/channel: Rename migration_channel_connect
2026-01-09 12:40 ` [PATCH v3 16/25] migration/channel: Rename migration_channel_connect Fabiano Rosas
@ 2026-01-20 11:10 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:10 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:18, Fabiano Rosas <farosas@suse.de> wrote:
> Rename migration_channel_connect to indicate this is the source
> side. Future patches will do similar changes to the incoming side and
> this will avoid inconsistencies in naming.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 9 +--------
> migration/channel.h | 2 +-
> migration/exec.c | 2 +-
> migration/fd.c | 2 +-
> migration/file.c | 2 +-
> migration/socket.c | 2 +-
> migration/tls.c | 2 +-
> 7 files changed, 7 insertions(+), 14 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index b8d757c17b..f41333adcc 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -61,14 +61,7 @@ out:
> }
> }
>
> -
> -/**
> - * @migration_channel_connect - Create new outgoing migration channel
> - *
> - * @s: Current migration state
> - * @ioc: Channel to which we are connecting
> - */
> -void migration_channel_connect(MigrationState *s, QIOChannel *ioc)
> +void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc)
> {
> trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc)));
>
> diff --git a/migration/channel.h b/migration/channel.h
> index b361e1c838..574bfec65c 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -28,7 +28,7 @@ typedef enum {
>
> void migration_channel_process_incoming(QIOChannel *ioc);
>
> -void migration_channel_connect(MigrationState *s, QIOChannel *ioc);
> +void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc);
>
> int migration_channel_read_peek(QIOChannel *ioc,
> const char *buf,
> diff --git a/migration/exec.c b/migration/exec.c
> index d83a07435a..d1629944dc 100644
> --- a/migration/exec.c
> +++ b/migration/exec.c
> @@ -55,7 +55,7 @@ void exec_start_outgoing_migration(MigrationState *s, strList *command,
> }
>
> qio_channel_set_name(ioc, "migration-exec-outgoing");
> - migration_channel_connect(s, ioc);
> + migration_channel_connect_outgoing(s, ioc);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/fd.c b/migration/fd.c
> index 0144a70742..150b236fbf 100644
> --- a/migration/fd.c
> +++ b/migration/fd.c
> @@ -70,7 +70,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
> }
>
> qio_channel_set_name(ioc, "migration-fd-outgoing");
> - migration_channel_connect(s, ioc);
> + migration_channel_connect_outgoing(s, ioc);
> object_unref(OBJECT(ioc));
> }
>
> diff --git a/migration/file.c b/migration/file.c
> index 7bb9c1c79f..935402f36b 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -122,7 +122,7 @@ void file_start_outgoing_migration(MigrationState *s,
> return;
> }
> qio_channel_set_name(ioc, "migration-file-outgoing");
> - migration_channel_connect(s, ioc);
> + migration_channel_connect_outgoing(s, ioc);
> }
>
> static gboolean file_accept_incoming_migration(QIOChannel *ioc,
> diff --git a/migration/socket.c b/migration/socket.c
> index 298bac30cc..611915f84d 100644
> --- a/migration/socket.c
> +++ b/migration/socket.c
> @@ -73,7 +73,7 @@ static void socket_outgoing_migration(QIOTask *task,
> }
>
> trace_migration_socket_outgoing_connected();
> - migration_channel_connect(data->s, sioc);
> + migration_channel_connect_outgoing(data->s, sioc);
> return;
> err:
> trace_migration_socket_outgoing_error(error_get_pretty(err));
> diff --git a/migration/tls.c b/migration/tls.c
> index 837b08294f..89ba52de02 100644
> --- a/migration/tls.c
> +++ b/migration/tls.c
> @@ -114,7 +114,7 @@ static void migration_tls_outgoing_handshake(QIOTask *task,
> }
>
> trace_migration_tls_outgoing_handshake_complete();
> - migration_channel_connect(s, ioc);
> + migration_channel_connect_outgoing(s, ioc);
> }
>
> QIOChannelTLS *migration_tls_client_create(QIOChannel *ioc,
> --
* Looks right.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 17/25] migration: Rename instances of start
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (15 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 16/25] migration/channel: Rename migration_channel_connect Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:21 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 18/25] migration: Move channel code to channel.c Fabiano Rosas
` (7 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Li Zhijian
To make it easier to follow the code, rename the functions that start
the migration thread and migration coroutine to contain the word
"start".
This will give new contributors the chance of seeing the word start
and reaching the actual migration code, instead of twists and turns of
qio_channel_add_watch and qio_task_run_in_thread.
Remove all other instances of "start" and use wording more suitable to
what the current migration stage is. The transport code such as
fd_start_migration_outgoing becomes fd_connect_outgoing, the early
setup code such as qemu_start_incoming_migration becomes
qemu_setup_incoming_migration and so on.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 4 ++--
migration/exec.c | 5 ++---
migration/exec.h | 5 ++---
migration/fd.c | 4 ++--
migration/fd.h | 6 +++---
migration/file.c | 6 +++---
migration/file.h | 6 +++---
migration/migration.c | 30 +++++++++++++++---------------
migration/migration.h | 3 ++-
migration/rdma.c | 21 ++++++++++-----------
migration/rdma.h | 6 +++---
migration/socket.c | 8 +++-----
migration/socket.h | 6 +++---
migration/trace-events | 10 +++++-----
14 files changed, 58 insertions(+), 62 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index f41333adcc..d1eec4942b 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -48,7 +48,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
}
if (migration_incoming_setup(ioc, ch, &local_err)) {
- migration_incoming_process();
+ migration_start_incoming();
}
}
out:
@@ -82,7 +82,7 @@ void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc)
migration_ioc_register_yank(ioc);
migration_outgoing_setup(ioc);
- migration_connect(s);
+ migration_start_outgoing(s);
}
diff --git a/migration/exec.c b/migration/exec.c
index d1629944dc..c3085e803e 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -40,8 +40,7 @@ const char *exec_get_cmd_path(void)
}
#endif
-void exec_start_outgoing_migration(MigrationState *s, strList *command,
- Error **errp)
+void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)
{
QIOChannel *ioc = NULL;
g_auto(GStrv) argv = strv_from_str_list(command);
@@ -68,7 +67,7 @@ static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
return G_SOURCE_REMOVE;
}
-void exec_start_incoming_migration(strList *command, Error **errp)
+void exec_connect_incoming(strList *command, Error **errp)
{
QIOChannel *ioc;
g_auto(GStrv) argv = strv_from_str_list(command);
diff --git a/migration/exec.h b/migration/exec.h
index 3107f205e3..e7e8e475ac 100644
--- a/migration/exec.h
+++ b/migration/exec.h
@@ -23,8 +23,7 @@
#ifdef WIN32
const char *exec_get_cmd_path(void);
#endif
-void exec_start_incoming_migration(strList *host_port, Error **errp);
+void exec_connect_incoming(strList *host_port, Error **errp);
-void exec_start_outgoing_migration(MigrationState *s, strList *host_port,
- Error **errp);
+void exec_connect_outgoing(MigrationState *s, strList *host_port, Error **errp);
#endif
diff --git a/migration/fd.c b/migration/fd.c
index 150b236fbf..b689426ad4 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -49,7 +49,7 @@ static bool migration_fd_valid(int fd)
return false;
}
-void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
+void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)
{
QIOChannel *ioc;
int fd = monitor_get_fd(monitor_cur(), fdname, errp);
@@ -83,7 +83,7 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
return G_SOURCE_REMOVE;
}
-void fd_start_incoming_migration(const char *fdname, Error **errp)
+void fd_connect_incoming(const char *fdname, Error **errp)
{
QIOChannel *ioc;
int fd = monitor_fd_param(monitor_cur(), fdname, errp);
diff --git a/migration/fd.h b/migration/fd.h
index b901bc014e..7211629270 100644
--- a/migration/fd.h
+++ b/migration/fd.h
@@ -16,8 +16,8 @@
#ifndef QEMU_MIGRATION_FD_H
#define QEMU_MIGRATION_FD_H
-void fd_start_incoming_migration(const char *fdname, Error **errp);
+void fd_connect_incoming(const char *fdname, Error **errp);
-void fd_start_outgoing_migration(MigrationState *s, const char *fdname,
- Error **errp);
+void fd_connect_outgoing(MigrationState *s, const char *fdname,
+ Error **errp);
#endif
diff --git a/migration/file.c b/migration/file.c
index 935402f36b..b7b0fb5194 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -93,8 +93,8 @@ out:
return ret;
}
-void file_start_outgoing_migration(MigrationState *s,
- FileMigrationArgs *file_args, Error **errp)
+void file_connect_outgoing(MigrationState *s,
+ FileMigrationArgs *file_args, Error **errp)
{
g_autoptr(QIOChannelFile) fioc = NULL;
g_autofree char *filename = g_strdup(file_args->filename);
@@ -173,7 +173,7 @@ static void file_create_incoming_channels(QIOChannel *ioc, char *filename,
}
}
-void file_start_incoming_migration(FileMigrationArgs *file_args, Error **errp)
+void file_connect_incoming(FileMigrationArgs *file_args, Error **errp)
{
g_autofree char *filename = g_strdup(file_args->filename);
QIOChannelFile *fioc = NULL;
diff --git a/migration/file.h b/migration/file.h
index 1a1115f7f1..9b1e874bb7 100644
--- a/migration/file.h
+++ b/migration/file.h
@@ -13,10 +13,10 @@
#include "channel.h"
#include "multifd.h"
-void file_start_incoming_migration(FileMigrationArgs *file_args, Error **errp);
+void file_connect_incoming(FileMigrationArgs *file_args, Error **errp);
-void file_start_outgoing_migration(MigrationState *s,
- FileMigrationArgs *file_args, Error **errp);
+void 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);
diff --git a/migration/migration.c b/migration/migration.c
index a052b99a19..83b85b20f9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -740,7 +740,7 @@ migration_incoming_state_setup(MigrationIncomingState *mis, Error **errp)
return true;
}
-static void qemu_start_incoming_migration(const char *uri, bool has_channels,
+static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
MigrationChannelList *channels,
Error **errp)
{
@@ -788,18 +788,18 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
- socket_start_incoming_migration(saddr, errp);
+ socket_connect_incoming(saddr, errp);
} else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
- fd_start_incoming_migration(saddr->u.fd.str, errp);
+ fd_connect_incoming(saddr->u.fd.str, errp);
}
#ifdef CONFIG_RDMA
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
- rdma_start_incoming_migration(&addr->u.rdma, errp);
+ rdma_connect_incoming(&addr->u.rdma, errp);
#endif
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
- exec_start_incoming_migration(addr->u.exec.args, errp);
+ exec_connect_incoming(addr->u.exec.args, errp);
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
- file_start_incoming_migration(&addr->u.file, errp);
+ file_connect_incoming(&addr->u.file, errp);
} else {
error_setg(errp, "unknown migration protocol: %s", uri);
}
@@ -1012,7 +1012,7 @@ static bool postcopy_try_recover(void)
return false;
}
-void migration_incoming_process(void)
+void migration_start_incoming(void)
{
if (postcopy_try_recover()) {
return;
@@ -1971,7 +1971,7 @@ void qmp_migrate_incoming(const char *uri, bool has_channels,
mis->exit_on_error =
has_exit_on_error ? exit_on_error : INMIGRATE_DEFAULT_EXIT_ON_ERROR;
- qemu_start_incoming_migration(uri, has_channels, channels, &local_err);
+ qemu_setup_incoming_migration(uri, has_channels, channels, &local_err);
if (local_err) {
yank_unregister_instance(MIGRATION_YANK_INSTANCE);
@@ -2018,7 +2018,7 @@ void qmp_migrate_recover(const char *uri, Error **errp)
* only re-setup the migration stream and poke existing migration
* to continue using that newly established channel.
*/
- qemu_start_incoming_migration(uri, false, NULL, errp);
+ qemu_setup_incoming_migration(uri, false, NULL, errp);
}
void qmp_migrate_pause(Error **errp)
@@ -2335,18 +2335,18 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
- socket_start_outgoing_migration(s, saddr, &local_err);
+ socket_connect_outgoing(s, saddr, &local_err);
} else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
- fd_start_outgoing_migration(s, saddr->u.fd.str, &local_err);
+ fd_connect_outgoing(s, saddr->u.fd.str, &local_err);
}
#ifdef CONFIG_RDMA
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
- rdma_start_outgoing_migration(s, &addr->u.rdma, &local_err);
+ rdma_connect_outgoing(s, &addr->u.rdma, &local_err);
#endif
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
- exec_start_outgoing_migration(s, addr->u.exec.args, &local_err);
+ exec_connect_outgoing(s, addr->u.exec.args, &local_err);
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
- file_start_outgoing_migration(s, &addr->u.file, &local_err);
+ file_connect_outgoing(s, &addr->u.file, &local_err);
} else {
error_setg(&local_err, "uri is not a valid migration protocol");
}
@@ -4032,7 +4032,7 @@ fail_setup:
return NULL;
}
-void migration_connect(MigrationState *s)
+void migration_start_outgoing(MigrationState *s)
{
Error *local_err = NULL;
uint64_t rate_limit;
diff --git a/migration/migration.h b/migration/migration.h
index b55cc40613..c4ea57d80a 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -539,7 +539,8 @@ void migration_connect_error_propagate(MigrationState *s, Error *error);
void migrate_error_propagate(MigrationState *s, Error *error);
bool migrate_has_error(MigrationState *s);
-void migration_connect(MigrationState *s);
+void migration_start_outgoing(MigrationState *s);
+void migration_start_incoming(void);
int migration_call_notifiers(MigrationEventType type, Error **errp);
diff --git a/migration/rdma.c b/migration/rdma.c
index d902c8669c..a23843bdc4 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3882,17 +3882,16 @@ static void rdma_accept_incoming_migration(void *opaque)
rdma->migration_started_on_destination = 1;
migration_incoming_setup(ioc, CH_MAIN, &error_abort);
- migration_incoming_process();
+ migration_start_incoming();
}
-void rdma_start_incoming_migration(InetSocketAddress *host_port,
- Error **errp)
+void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp)
{
MigrationState *s = migrate_get_current();
int ret;
RDMAContext *rdma;
- trace_rdma_start_incoming_migration();
+ trace_rdma_connect_incoming();
/* Avoid ram_block_discard_disable(), cannot change during migration. */
if (ram_block_discard_is_required()) {
@@ -3910,7 +3909,7 @@ void rdma_start_incoming_migration(InetSocketAddress *host_port,
goto err;
}
- trace_rdma_start_incoming_migration_after_dest_init();
+ trace_rdma_connect_incoming_after_dest_init();
ret = rdma_listen(rdma->listen_id, 5);
@@ -3919,7 +3918,7 @@ void rdma_start_incoming_migration(InetSocketAddress *host_port,
goto cleanup_rdma;
}
- trace_rdma_start_incoming_migration_after_rdma_listen();
+ trace_rdma_connect_incoming_after_rdma_listen();
s->rdma_migration = true;
qemu_set_fd_handler(rdma->channel->fd, rdma_accept_incoming_migration,
NULL, (void *)(intptr_t)rdma);
@@ -3934,8 +3933,8 @@ err:
g_free(rdma);
}
-void rdma_start_outgoing_migration(void *opaque,
- InetSocketAddress *host_port, Error **errp)
+void rdma_connect_outgoing(void *opaque,
+ InetSocketAddress *host_port, Error **errp)
{
MigrationState *s = opaque;
RDMAContext *rdma_return_path = NULL;
@@ -3959,7 +3958,7 @@ void rdma_start_outgoing_migration(void *opaque,
goto err;
}
- trace_rdma_start_outgoing_migration_after_rdma_source_init();
+ trace_rdma_connect_outgoing_after_rdma_source_init();
ret = qemu_rdma_connect(rdma, false, errp);
if (ret < 0) {
@@ -3992,11 +3991,11 @@ void rdma_start_outgoing_migration(void *opaque,
rdma_return_path->is_return_path = true;
}
- trace_rdma_start_outgoing_migration_after_rdma_connect();
+ trace_rdma_connect_outgoing_after_rdma_connect();
s->rdma_migration = true;
migration_outgoing_setup(rdma_new_output(rdma));
- migration_connect(s);
+ migration_start_outgoing(s);
return;
return_path_err:
qemu_rdma_cleanup(rdma);
diff --git a/migration/rdma.h b/migration/rdma.h
index f74f16a459..170c25cf44 100644
--- a/migration/rdma.h
+++ b/migration/rdma.h
@@ -21,10 +21,10 @@
#include "system/memory.h"
-void rdma_start_outgoing_migration(void *opaque, InetSocketAddress *host_port,
- Error **errp);
+void rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,
+ Error **errp);
-void rdma_start_incoming_migration(InetSocketAddress *host_port, Error **errp);
+void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp);
/*
* Constants used by rdma return codes
diff --git a/migration/socket.c b/migration/socket.c
index 611915f84d..ac3183d5d5 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -80,9 +80,8 @@ err:
migration_connect_error_propagate(data->s, err);
}
-void socket_start_outgoing_migration(MigrationState *s,
- SocketAddress *saddr,
- Error **errp)
+void socket_connect_outgoing(MigrationState *s, SocketAddress *saddr,
+ Error **errp)
{
QIOChannelSocket *sioc = qio_channel_socket_new();
struct SocketConnectData *data = g_new0(struct SocketConnectData, 1);
@@ -140,8 +139,7 @@ socket_incoming_migration_end(void *opaque)
object_unref(OBJECT(listener));
}
-void socket_start_incoming_migration(SocketAddress *saddr,
- Error **errp)
+void socket_connect_incoming(SocketAddress *saddr, Error **errp)
{
QIONetListener *listener = qio_net_listener_new();
MigrationIncomingState *mis = migration_incoming_get_current();
diff --git a/migration/socket.h b/migration/socket.h
index 04ebbe95a1..f0c89b64c7 100644
--- a/migration/socket.h
+++ b/migration/socket.h
@@ -23,10 +23,10 @@
void socket_send_channel_create(QIOTaskFunc f, void *data);
-void socket_start_incoming_migration(SocketAddress *saddr, Error **errp);
+void socket_connect_incoming(SocketAddress *saddr, Error **errp);
-void socket_start_outgoing_migration(MigrationState *s,
- SocketAddress *saddr, Error **errp);
+void socket_connect_outgoing(MigrationState *s,
+ SocketAddress *saddr, Error **errp);
void socket_cleanup_outgoing_migration(void);
#endif
diff --git a/migration/trace-events b/migration/trace-events
index cbf10d0b63..91d7506634 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -271,11 +271,11 @@ rdma_registration_handle_wait(void) ""
rdma_registration_start(uint64_t flags) "%" PRIu64
rdma_registration_stop(uint64_t flags) "%" PRIu64
rdma_registration_stop_ram(void) ""
-rdma_start_incoming_migration(void) ""
-rdma_start_incoming_migration_after_dest_init(void) ""
-rdma_start_incoming_migration_after_rdma_listen(void) ""
-rdma_start_outgoing_migration_after_rdma_connect(void) ""
-rdma_start_outgoing_migration_after_rdma_source_init(void) ""
+rdma_connect_incoming(void) ""
+rdma_connect_incoming_after_dest_init(void) ""
+rdma_connect_incoming_after_rdma_listen(void) ""
+rdma_connect_outgoing_after_rdma_connect(void) ""
+rdma_connect_outgoing_after_rdma_source_init(void) ""
# postcopy-ram.c
postcopy_discard_send_finish(const char *ramblock, int nwords, int ncmds) "%s mask words sent=%d in %d commands"
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 17/25] migration: Rename instances of start
2026-01-09 12:40 ` [PATCH v3 17/25] migration: Rename instances of start Fabiano Rosas
@ 2026-01-20 11:21 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:21 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Li Zhijian
On Fri, 9 Jan 2026 at 18:19, Fabiano Rosas <farosas@suse.de> wrote:
> To make it easier to follow the code, rename the functions that start
> the migration thread and migration coroutine to contain the word
> "start".
>
> This will give new contributors the chance of seeing the word start
> and reaching the actual migration code, instead of twists and turns of
> qio_channel_add_watch and qio_task_run_in_thread.
>
> Remove all other instances of "start" and use wording more suitable to
> what the current migration stage is. The transport code such as
> fd_start_migration_outgoing becomes fd_connect_outgoing, the early
> setup code such as qemu_start_incoming_migration becomes
> qemu_setup_incoming_migration and so on.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 4 ++--
> migration/exec.c | 5 ++---
> migration/exec.h | 5 ++---
> migration/fd.c | 4 ++--
> migration/fd.h | 6 +++---
> migration/file.c | 6 +++---
> migration/file.h | 6 +++---
> migration/migration.c | 30 +++++++++++++++---------------
> migration/migration.h | 3 ++-
> migration/rdma.c | 21 ++++++++++-----------
> migration/rdma.h | 6 +++---
> migration/socket.c | 8 +++-----
> migration/socket.h | 6 +++---
> migration/trace-events | 10 +++++-----
> 14 files changed, 58 insertions(+), 62 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index f41333adcc..d1eec4942b 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -48,7 +48,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
> }
>
> if (migration_incoming_setup(ioc, ch, &local_err)) {
> - migration_incoming_process();
> + migration_start_incoming();
> }
> }
> out:
> @@ -82,7 +82,7 @@ void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc)
>
> migration_ioc_register_yank(ioc);
> migration_outgoing_setup(ioc);
> - migration_connect(s);
> + migration_start_outgoing(s);
> }
>
>
> diff --git a/migration/exec.c b/migration/exec.c
> index d1629944dc..c3085e803e 100644
> --- a/migration/exec.c
> +++ b/migration/exec.c
> @@ -40,8 +40,7 @@ const char *exec_get_cmd_path(void)
> }
> #endif
>
> -void exec_start_outgoing_migration(MigrationState *s, strList *command,
> - Error **errp)
> +void exec_connect_outgoing(MigrationState *s, strList *command, Error **errp)
> {
> QIOChannel *ioc = NULL;
> g_auto(GStrv) argv = strv_from_str_list(command);
> @@ -68,7 +67,7 @@ static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
> return G_SOURCE_REMOVE;
> }
>
> -void exec_start_incoming_migration(strList *command, Error **errp)
> +void exec_connect_incoming(strList *command, Error **errp)
> {
> QIOChannel *ioc;
> g_auto(GStrv) argv = strv_from_str_list(command);
> diff --git a/migration/exec.h b/migration/exec.h
> index 3107f205e3..e7e8e475ac 100644
> --- a/migration/exec.h
> +++ b/migration/exec.h
> @@ -23,8 +23,7 @@
> #ifdef WIN32
> const char *exec_get_cmd_path(void);
> #endif
> -void exec_start_incoming_migration(strList *host_port, Error **errp);
> +void exec_connect_incoming(strList *host_port, Error **errp);
>
> -void exec_start_outgoing_migration(MigrationState *s, strList *host_port,
> - Error **errp);
> +void exec_connect_outgoing(MigrationState *s, strList *host_port, Error **errp);
> #endif
> diff --git a/migration/fd.c b/migration/fd.c
> index 150b236fbf..b689426ad4 100644
> --- a/migration/fd.c
> +++ b/migration/fd.c
> @@ -49,7 +49,7 @@ static bool migration_fd_valid(int fd)
> return false;
> }
>
> -void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
> +void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)
> {
> QIOChannel *ioc;
> int fd = monitor_get_fd(monitor_cur(), fdname, errp);
> @@ -83,7 +83,7 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
> return G_SOURCE_REMOVE;
> }
>
> -void fd_start_incoming_migration(const char *fdname, Error **errp)
> +void fd_connect_incoming(const char *fdname, Error **errp)
> {
> QIOChannel *ioc;
> int fd = monitor_fd_param(monitor_cur(), fdname, errp);
> diff --git a/migration/fd.h b/migration/fd.h
> index b901bc014e..7211629270 100644
> --- a/migration/fd.h
> +++ b/migration/fd.h
> @@ -16,8 +16,8 @@
>
> #ifndef QEMU_MIGRATION_FD_H
> #define QEMU_MIGRATION_FD_H
> -void fd_start_incoming_migration(const char *fdname, Error **errp);
> +void fd_connect_incoming(const char *fdname, Error **errp);
>
> -void fd_start_outgoing_migration(MigrationState *s, const char *fdname,
> - Error **errp);
> +void fd_connect_outgoing(MigrationState *s, const char *fdname,
> + Error **errp);
> #endif
> diff --git a/migration/file.c b/migration/file.c
> index 935402f36b..b7b0fb5194 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -93,8 +93,8 @@ out:
> return ret;
> }
>
> -void file_start_outgoing_migration(MigrationState *s,
> - FileMigrationArgs *file_args, Error **errp)
> +void file_connect_outgoing(MigrationState *s,
> + FileMigrationArgs *file_args, Error **errp)
> {
> g_autoptr(QIOChannelFile) fioc = NULL;
> g_autofree char *filename = g_strdup(file_args->filename);
> @@ -173,7 +173,7 @@ static void file_create_incoming_channels(QIOChannel *ioc, char *filename,
> }
> }
>
> -void file_start_incoming_migration(FileMigrationArgs *file_args, Error **errp)
> +void file_connect_incoming(FileMigrationArgs *file_args, Error **errp)
> {
> g_autofree char *filename = g_strdup(file_args->filename);
> QIOChannelFile *fioc = NULL;
> diff --git a/migration/file.h b/migration/file.h
> index 1a1115f7f1..9b1e874bb7 100644
> --- a/migration/file.h
> +++ b/migration/file.h
> @@ -13,10 +13,10 @@
> #include "channel.h"
> #include "multifd.h"
>
> -void file_start_incoming_migration(FileMigrationArgs *file_args, Error **errp);
> +void file_connect_incoming(FileMigrationArgs *file_args, Error **errp);
>
> -void file_start_outgoing_migration(MigrationState *s,
> - FileMigrationArgs *file_args, Error **errp);
> +void 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);
> diff --git a/migration/migration.c b/migration/migration.c
> index a052b99a19..83b85b20f9 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -740,7 +740,7 @@ migration_incoming_state_setup(MigrationIncomingState *mis, Error **errp)
> return true;
> }
>
> -static void qemu_start_incoming_migration(const char *uri, bool has_channels,
> +static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
> MigrationChannelList *channels,
> Error **errp)
> {
> @@ -788,18 +788,18 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
> if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
> saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
> saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
> - socket_start_incoming_migration(saddr, errp);
> + socket_connect_incoming(saddr, errp);
> } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> - fd_start_incoming_migration(saddr->u.fd.str, errp);
> + fd_connect_incoming(saddr->u.fd.str, errp);
> }
> #ifdef CONFIG_RDMA
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
> - rdma_start_incoming_migration(&addr->u.rdma, errp);
> + rdma_connect_incoming(&addr->u.rdma, errp);
> #endif
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> - exec_start_incoming_migration(addr->u.exec.args, errp);
> + exec_connect_incoming(addr->u.exec.args, errp);
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
> - file_start_incoming_migration(&addr->u.file, errp);
> + file_connect_incoming(&addr->u.file, errp);
> } else {
> error_setg(errp, "unknown migration protocol: %s", uri);
> }
> @@ -1012,7 +1012,7 @@ static bool postcopy_try_recover(void)
> return false;
> }
>
> -void migration_incoming_process(void)
> +void migration_start_incoming(void)
> {
> if (postcopy_try_recover()) {
> return;
> @@ -1971,7 +1971,7 @@ void qmp_migrate_incoming(const char *uri, bool has_channels,
> mis->exit_on_error =
> has_exit_on_error ? exit_on_error : INMIGRATE_DEFAULT_EXIT_ON_ERROR;
>
> - qemu_start_incoming_migration(uri, has_channels, channels, &local_err);
> + qemu_setup_incoming_migration(uri, has_channels, channels, &local_err);
>
> if (local_err) {
> yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> @@ -2018,7 +2018,7 @@ void qmp_migrate_recover(const char *uri, Error **errp)
> * only re-setup the migration stream and poke existing migration
> * to continue using that newly established channel.
> */
> - qemu_start_incoming_migration(uri, false, NULL, errp);
> + qemu_setup_incoming_migration(uri, false, NULL, errp);
> }
>
> void qmp_migrate_pause(Error **errp)
> @@ -2335,18 +2335,18 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
> if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
> saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
> saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
> - socket_start_outgoing_migration(s, saddr, &local_err);
> + socket_connect_outgoing(s, saddr, &local_err);
> } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> - fd_start_outgoing_migration(s, saddr->u.fd.str, &local_err);
> + fd_connect_outgoing(s, saddr->u.fd.str, &local_err);
> }
> #ifdef CONFIG_RDMA
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
> - rdma_start_outgoing_migration(s, &addr->u.rdma, &local_err);
> + rdma_connect_outgoing(s, &addr->u.rdma, &local_err);
> #endif
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> - exec_start_outgoing_migration(s, addr->u.exec.args, &local_err);
> + exec_connect_outgoing(s, addr->u.exec.args, &local_err);
> } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
> - file_start_outgoing_migration(s, &addr->u.file, &local_err);
> + file_connect_outgoing(s, &addr->u.file, &local_err);
> } else {
> error_setg(&local_err, "uri is not a valid migration protocol");
> }
> @@ -4032,7 +4032,7 @@ fail_setup:
> return NULL;
> }
>
> -void migration_connect(MigrationState *s)
> +void migration_start_outgoing(MigrationState *s)
> {
> Error *local_err = NULL;
> uint64_t rate_limit;
> diff --git a/migration/migration.h b/migration/migration.h
> index b55cc40613..c4ea57d80a 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -539,7 +539,8 @@ void migration_connect_error_propagate(MigrationState *s, Error *error);
> void migrate_error_propagate(MigrationState *s, Error *error);
> bool migrate_has_error(MigrationState *s);
>
> -void migration_connect(MigrationState *s);
> +void migration_start_outgoing(MigrationState *s);
> +void migration_start_incoming(void);
>
> int migration_call_notifiers(MigrationEventType type, Error **errp);
>
> diff --git a/migration/rdma.c b/migration/rdma.c
> index d902c8669c..a23843bdc4 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -3882,17 +3882,16 @@ static void rdma_accept_incoming_migration(void *opaque)
>
> rdma->migration_started_on_destination = 1;
> migration_incoming_setup(ioc, CH_MAIN, &error_abort);
> - migration_incoming_process();
> + migration_start_incoming();
> }
>
> -void rdma_start_incoming_migration(InetSocketAddress *host_port,
> - Error **errp)
> +void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp)
> {
> MigrationState *s = migrate_get_current();
> int ret;
> RDMAContext *rdma;
>
> - trace_rdma_start_incoming_migration();
> + trace_rdma_connect_incoming();
>
> /* Avoid ram_block_discard_disable(), cannot change during migration. */
> if (ram_block_discard_is_required()) {
> @@ -3910,7 +3909,7 @@ void rdma_start_incoming_migration(InetSocketAddress *host_port,
> goto err;
> }
>
> - trace_rdma_start_incoming_migration_after_dest_init();
> + trace_rdma_connect_incoming_after_dest_init();
>
> ret = rdma_listen(rdma->listen_id, 5);
>
> @@ -3919,7 +3918,7 @@ void rdma_start_incoming_migration(InetSocketAddress *host_port,
> goto cleanup_rdma;
> }
>
> - trace_rdma_start_incoming_migration_after_rdma_listen();
> + trace_rdma_connect_incoming_after_rdma_listen();
> s->rdma_migration = true;
> qemu_set_fd_handler(rdma->channel->fd, rdma_accept_incoming_migration,
> NULL, (void *)(intptr_t)rdma);
> @@ -3934,8 +3933,8 @@ err:
> g_free(rdma);
> }
>
> -void rdma_start_outgoing_migration(void *opaque,
> - InetSocketAddress *host_port, Error **errp)
> +void rdma_connect_outgoing(void *opaque,
> + InetSocketAddress *host_port, Error **errp)
> {
> MigrationState *s = opaque;
> RDMAContext *rdma_return_path = NULL;
> @@ -3959,7 +3958,7 @@ void rdma_start_outgoing_migration(void *opaque,
> goto err;
> }
>
> - trace_rdma_start_outgoing_migration_after_rdma_source_init();
> + trace_rdma_connect_outgoing_after_rdma_source_init();
> ret = qemu_rdma_connect(rdma, false, errp);
>
> if (ret < 0) {
> @@ -3992,11 +3991,11 @@ void rdma_start_outgoing_migration(void *opaque,
> rdma_return_path->is_return_path = true;
> }
>
> - trace_rdma_start_outgoing_migration_after_rdma_connect();
> + trace_rdma_connect_outgoing_after_rdma_connect();
>
> s->rdma_migration = true;
> migration_outgoing_setup(rdma_new_output(rdma));
> - migration_connect(s);
> + migration_start_outgoing(s);
> return;
> return_path_err:
> qemu_rdma_cleanup(rdma);
> diff --git a/migration/rdma.h b/migration/rdma.h
> index f74f16a459..170c25cf44 100644
> --- a/migration/rdma.h
> +++ b/migration/rdma.h
> @@ -21,10 +21,10 @@
>
> #include "system/memory.h"
>
> -void rdma_start_outgoing_migration(void *opaque, InetSocketAddress *host_port,
> - Error **errp);
> +void rdma_connect_outgoing(void *opaque, InetSocketAddress *host_port,
> + Error **errp);
>
> -void rdma_start_incoming_migration(InetSocketAddress *host_port, Error **errp);
> +void rdma_connect_incoming(InetSocketAddress *host_port, Error **errp);
>
> /*
> * Constants used by rdma return codes
> diff --git a/migration/socket.c b/migration/socket.c
> index 611915f84d..ac3183d5d5 100644
> --- a/migration/socket.c
> +++ b/migration/socket.c
> @@ -80,9 +80,8 @@ err:
> migration_connect_error_propagate(data->s, err);
> }
>
> -void socket_start_outgoing_migration(MigrationState *s,
> - SocketAddress *saddr,
> - Error **errp)
> +void socket_connect_outgoing(MigrationState *s, SocketAddress *saddr,
> + Error **errp)
> {
> QIOChannelSocket *sioc = qio_channel_socket_new();
> struct SocketConnectData *data = g_new0(struct SocketConnectData, 1);
> @@ -140,8 +139,7 @@ socket_incoming_migration_end(void *opaque)
> object_unref(OBJECT(listener));
> }
>
> -void socket_start_incoming_migration(SocketAddress *saddr,
> - Error **errp)
> +void socket_connect_incoming(SocketAddress *saddr, Error **errp)
> {
> QIONetListener *listener = qio_net_listener_new();
> MigrationIncomingState *mis = migration_incoming_get_current();
> diff --git a/migration/socket.h b/migration/socket.h
> index 04ebbe95a1..f0c89b64c7 100644
> --- a/migration/socket.h
> +++ b/migration/socket.h
> @@ -23,10 +23,10 @@
>
> void socket_send_channel_create(QIOTaskFunc f, void *data);
>
> -void socket_start_incoming_migration(SocketAddress *saddr, Error **errp);
> +void socket_connect_incoming(SocketAddress *saddr, Error **errp);
>
> -void socket_start_outgoing_migration(MigrationState *s,
> - SocketAddress *saddr, Error **errp);
> +void socket_connect_outgoing(MigrationState *s,
> + SocketAddress *saddr, Error **errp);
> void socket_cleanup_outgoing_migration(void);
>
> #endif
> diff --git a/migration/trace-events b/migration/trace-events
> index cbf10d0b63..91d7506634 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -271,11 +271,11 @@ rdma_registration_handle_wait(void) ""
> rdma_registration_start(uint64_t flags) "%" PRIu64
> rdma_registration_stop(uint64_t flags) "%" PRIu64
> rdma_registration_stop_ram(void) ""
> -rdma_start_incoming_migration(void) ""
> -rdma_start_incoming_migration_after_dest_init(void) ""
> -rdma_start_incoming_migration_after_rdma_listen(void) ""
> -rdma_start_outgoing_migration_after_rdma_connect(void) ""
> -rdma_start_outgoing_migration_after_rdma_source_init(void) ""
> +rdma_connect_incoming(void) ""
> +rdma_connect_incoming_after_dest_init(void) ""
> +rdma_connect_incoming_after_rdma_listen(void) ""
> +rdma_connect_outgoing_after_rdma_connect(void) ""
> +rdma_connect_outgoing_after_rdma_source_init(void) ""
>
> # postcopy-ram.c
> postcopy_discard_send_finish(const char *ramblock, int nwords, int ncmds) "%s mask words sent=%d in %d commands"
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 18/25] migration: Move channel code to channel.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (16 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 17/25] migration: Rename instances of start Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-09 12:40 ` [PATCH v3 19/25] migration: Move transport connection code into channel.c Fabiano Rosas
` (6 subsequent siblings)
24 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Li Zhijian
Move the code responsible for the various channels connection into
channel.c. This is all executed before the migration_thread and
process_incoming_migration_co are running, so it helps the reasoning
to have them out of migration.c.
migration_ioc_process_incoming becomes migration_channel_identify
which is more in line with what the function does.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 99 ++++++++++++++++++++++++++++++++++++++++++-
migration/channel.h | 4 ++
migration/migration.c | 96 -----------------------------------------
migration/migration.h | 4 --
migration/rdma.c | 1 +
5 files changed, 103 insertions(+), 101 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index d1eec4942b..f61d30d986 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -14,13 +14,110 @@
#include "channel.h"
#include "tls.h"
#include "migration.h"
+#include "multifd.h"
+#include "savevm.h"
#include "trace.h"
+#include "options.h"
#include "qapi/error.h"
#include "io/channel-tls.h"
#include "io/channel-socket.h"
#include "qemu/yank.h"
#include "yank_functions.h"
+bool migration_has_main_and_multifd_channels(void)
+{
+ MigrationIncomingState *mis = migration_incoming_get_current();
+ if (!mis->from_src_file) {
+ /* main channel not established */
+ return false;
+ }
+
+ if (migrate_multifd() && !multifd_recv_all_channels_created()) {
+ return false;
+ }
+
+ /* main and all multifd channels are established */
+ return true;
+}
+
+/**
+ * @migration_has_all_channels: We have received all channels that we need
+ *
+ * Returns true when we have got connections to all the channels that
+ * we need for migration.
+ */
+bool migration_has_all_channels(void)
+{
+ if (!migration_has_main_and_multifd_channels()) {
+ return false;
+ }
+
+ MigrationIncomingState *mis = migration_incoming_get_current();
+ if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) {
+ return false;
+ }
+
+ return true;
+}
+
+static MigChannelType migration_channel_identify(MigrationIncomingState *mis,
+ QIOChannel *ioc, Error **errp)
+{
+ MigChannelType channel = CH_NONE;
+ uint32_t channel_magic = 0;
+ int ret = 0;
+
+ if (!migration_has_main_and_multifd_channels()) {
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
+ /*
+ * With multiple channels, it is possible that we receive channels
+ * out of order on destination side, causing incorrect mapping of
+ * source channels on destination side. Check channel MAGIC to
+ * decide type of channel. Please note this is best effort,
+ * postcopy preempt channel does not send any magic number so
+ * avoid it for postcopy live migration. Also tls live migration
+ * already does tls handshake while initializing main channel so
+ * with tls this issue is not possible.
+ */
+ ret = migration_channel_read_peek(ioc, (void *)&channel_magic,
+ sizeof(channel_magic), errp);
+ if (ret != 0) {
+ goto out;
+ }
+
+ channel_magic = be32_to_cpu(channel_magic);
+ if (channel_magic == QEMU_VM_FILE_MAGIC) {
+ channel = CH_MAIN;
+ } else if (channel_magic == MULTIFD_MAGIC) {
+ assert(migrate_multifd());
+ channel = CH_MULTIFD;
+ } else if (!mis->from_src_file &&
+ mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
+ /* reconnect main channel for postcopy recovery */
+ channel = CH_MAIN;
+ } else {
+ error_setg(errp, "unknown channel magic: %u", channel_magic);
+ }
+ } else if (mis->from_src_file && migrate_multifd()) {
+ /*
+ * Non-peekable channels like tls/file are processed as
+ * multifd channels when multifd is enabled.
+ */
+ channel = CH_MULTIFD;
+ } else if (!mis->from_src_file) {
+ channel = CH_MAIN;
+ } else {
+ error_setg(errp, "non-peekable channel used without multifd");
+ }
+ } else {
+ assert(migrate_postcopy_preempt());
+ channel = CH_POSTCOPY;
+ }
+
+out:
+ return channel;
+}
+
/**
* @migration_channel_process_incoming - Create new incoming migration channel
*
@@ -42,7 +139,7 @@ void migration_channel_process_incoming(QIOChannel *ioc)
migration_tls_channel_process_incoming(ioc, &local_err);
} else {
migration_ioc_register_yank(ioc);
- ch = migration_ioc_process_incoming(ioc, &local_err);
+ ch = migration_channel_identify(mis, ioc, &local_err);
if (!ch) {
goto out;
}
diff --git a/migration/channel.h b/migration/channel.h
index 574bfec65c..19aa5ab795 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -34,4 +34,8 @@ int migration_channel_read_peek(QIOChannel *ioc,
const char *buf,
const size_t buflen,
Error **errp);
+
+bool migration_has_main_and_multifd_channels(void);
+bool migration_has_all_channels(void);
+
#endif
diff --git a/migration/migration.c b/migration/migration.c
index 83b85b20f9..aa291f1fed 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -927,8 +927,6 @@ out:
migrate_incoming_unref_outgoing_state();
}
-static bool migration_has_main_and_multifd_channels(void);
-
/*
* Returns whether all the necessary channels to proceed with the
* incoming migration have been established without error.
@@ -1022,100 +1020,6 @@ void migration_start_incoming(void)
qemu_coroutine_enter(co);
}
-static bool migration_has_main_and_multifd_channels(void)
-{
- MigrationIncomingState *mis = migration_incoming_get_current();
- if (!mis->from_src_file) {
- /* main channel not established */
- return false;
- }
-
- if (migrate_multifd() && !multifd_recv_all_channels_created()) {
- return false;
- }
-
- /* main and all multifd channels are established */
- return true;
-}
-
-MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
-{
- MigrationIncomingState *mis = migration_incoming_get_current();
- MigChannelType channel = CH_NONE;
- uint32_t channel_magic = 0;
- int ret = 0;
-
- if (!migration_has_main_and_multifd_channels()) {
- if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
- /*
- * With multiple channels, it is possible that we receive channels
- * out of order on destination side, causing incorrect mapping of
- * source channels on destination side. Check channel MAGIC to
- * decide type of channel. Please note this is best effort,
- * postcopy preempt channel does not send any magic number so
- * avoid it for postcopy live migration. Also tls live migration
- * already does tls handshake while initializing main channel so
- * with tls this issue is not possible.
- */
- ret = migration_channel_read_peek(ioc, (void *)&channel_magic,
- sizeof(channel_magic), errp);
- if (ret != 0) {
- goto out;
- }
-
- channel_magic = be32_to_cpu(channel_magic);
- if (channel_magic == QEMU_VM_FILE_MAGIC) {
- channel = CH_MAIN;
- } else if (channel_magic == MULTIFD_MAGIC) {
- assert(migrate_multifd());
- channel = CH_MULTIFD;
- } else if (!mis->from_src_file &&
- mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
- /* reconnect main channel for postcopy recovery */
- channel = CH_MAIN;
- } else {
- error_setg(errp, "unknown channel magic: %u", channel_magic);
- }
- } else if (mis->from_src_file && migrate_multifd()) {
- /*
- * Non-peekable channels like tls/file are processed as
- * multifd channels when multifd is enabled.
- */
- channel = CH_MULTIFD;
- } else if (!mis->from_src_file) {
- channel = CH_MAIN;
- } else {
- error_setg(errp, "non-peekable channel used without multifd");
- }
- } else {
- assert(migrate_postcopy_preempt());
- channel = CH_POSTCOPY;
- }
-
-out:
- return channel;
-}
-
-/**
- * @migration_has_all_channels: We have received all channels that we need
- *
- * Returns true when we have got connections to all the channels that
- * we need for migration.
- */
-bool migration_has_all_channels(void)
-{
- if (!migration_has_main_and_multifd_channels()) {
- return false;
- }
-
- MigrationIncomingState *mis = migration_incoming_get_current();
- if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) {
- return false;
- }
-
- return true;
-}
-
int migrate_send_rp_switchover_ack(MigrationIncomingState *mis)
{
return migrate_send_rp_message(mis, MIG_RP_MSG_SWITCHOVER_ACK, 0, NULL);
diff --git a/migration/migration.h b/migration/migration.h
index c4ea57d80a..b6888daced 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -28,7 +28,6 @@
#include "postcopy-ram.h"
#include "system/runstate.h"
#include "migration/misc.h"
-#include "channel.h"
#define MIGRATION_THREAD_SNAPSHOT "mig/snapshot"
#define MIGRATION_THREAD_DIRTY_RATE "mig/dirtyrate"
@@ -528,13 +527,10 @@ struct MigrationState {
void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
MigrationStatus new_state);
-MigChannelType migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
void migration_incoming_process(void);
bool migration_incoming_setup(QIOChannel *ioc, uint8_t channel, Error **errp);
void migration_outgoing_setup(QIOChannel *ioc);
-bool migration_has_all_channels(void);
-
void migration_connect_error_propagate(MigrationState *s, Error *error);
void migrate_error_propagate(MigrationState *s, Error *error);
bool migrate_has_error(MigrationState *s);
diff --git a/migration/rdma.c b/migration/rdma.c
index a23843bdc4..b726392097 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -18,6 +18,7 @@
#include "channel.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
+#include "channel.h"
#include "exec/target_page.h"
#include "rdma.h"
#include "migration.h"
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH v3 19/25] migration: Move transport connection code into channel.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (17 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 18/25] migration: Move channel code to channel.c Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 9:40 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 20/25] migration: Move channel parsing to channel.c Fabiano Rosas
` (5 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Move the <transport>_connect_incoming|outgoing functions to channel.c.
It leaves migration.c to deal with the established connection only.
(I sorted the includes)
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 66 +++++++++++++++++++++++++++++++++++++++----
migration/channel.h | 4 +++
migration/migration.c | 46 ++----------------------------
3 files changed, 67 insertions(+), 49 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index f61d30d986..56c80b5cdf 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -12,18 +12,74 @@
#include "qemu/osdep.h"
#include "channel.h"
-#include "tls.h"
+#include "exec.h"
+#include "fd.h"
+#include "file.h"
+#include "io/channel-socket.h"
+#include "io/channel-tls.h"
#include "migration.h"
#include "multifd.h"
-#include "savevm.h"
-#include "trace.h"
#include "options.h"
+#include "qapi/qapi-types-migration.h"
#include "qapi/error.h"
-#include "io/channel-tls.h"
-#include "io/channel-socket.h"
+#include "qemu-file.h"
#include "qemu/yank.h"
+#include "rdma.h"
+#include "savevm.h"
+#include "socket.h"
+#include "tls.h"
+#include "trace.h"
#include "yank_functions.h"
+void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
+ Error **errp)
+{
+ 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);
+ } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
+ 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);
+#endif
+ } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
+ 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);
+ } else {
+ error_setg(errp, "uri is not a valid migration protocol");
+ }
+}
+
+void migration_connect_incoming(MigrationAddress *addr, Error **errp)
+{
+ 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_incoming(saddr, errp);
+ } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
+ fd_connect_incoming(saddr->u.fd.str, errp);
+ }
+#ifdef CONFIG_RDMA
+ } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
+ rdma_connect_incoming(&addr->u.rdma, errp);
+#endif
+ } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
+ exec_connect_incoming(addr->u.exec.args, errp);
+ } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
+ file_connect_incoming(&addr->u.file, errp);
+ } else {
+ error_setg(errp, "unknown migration protocol");
+ }
+}
+
bool migration_has_main_and_multifd_channels(void)
{
MigrationIncomingState *mis = migration_incoming_get_current();
diff --git a/migration/channel.h b/migration/channel.h
index 19aa5ab795..8264fe327d 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -17,6 +17,7 @@
#define QEMU_MIGRATION_CHANNEL_H
#include "io/channel.h"
+#include "qapi/qapi-types-migration.h"
/* Migration channel types */
typedef enum {
@@ -38,4 +39,7 @@ int migration_channel_read_peek(QIOChannel *ioc,
bool migration_has_main_and_multifd_channels(void);
bool migration_has_all_channels(void);
+void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
+ Error **errp);
+void migration_connect_incoming(MigrationAddress *addr, Error **errp);
#endif
diff --git a/migration/migration.c b/migration/migration.c
index aa291f1fed..3c93fb23cc 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -20,13 +20,10 @@
#include "qemu/main-loop.h"
#include "migration/blocker.h"
#include "exec.h"
-#include "fd.h"
#include "file.h"
-#include "socket.h"
#include "system/runstate.h"
#include "system/system.h"
#include "system/cpu-throttle.h"
-#include "rdma.h"
#include "ram.h"
#include "migration/cpr.h"
#include "migration/global_state.h"
@@ -783,26 +780,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
return;
}
- 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_incoming(saddr, errp);
- } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
- fd_connect_incoming(saddr->u.fd.str, errp);
- }
-#ifdef CONFIG_RDMA
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
- rdma_connect_incoming(&addr->u.rdma, errp);
-#endif
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
- exec_connect_incoming(addr->u.exec.args, errp);
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
- file_connect_incoming(&addr->u.file, errp);
- } else {
- error_setg(errp, "unknown migration protocol: %s", uri);
- }
+ migration_connect_incoming(addr, errp);
/* Close cpr socket to tell source that we are listening */
cpr_state_close();
@@ -2234,31 +2212,11 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
MigrationState *s = migrate_get_current();
Error *local_err = 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, &local_err);
- } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
- fd_connect_outgoing(s, saddr->u.fd.str, &local_err);
- }
-#ifdef CONFIG_RDMA
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
- rdma_connect_outgoing(s, &addr->u.rdma, &local_err);
-#endif
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
- exec_connect_outgoing(s, addr->u.exec.args, &local_err);
- } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
- file_connect_outgoing(s, &addr->u.file, &local_err);
- } else {
- error_setg(&local_err, "uri is not a valid migration protocol");
- }
+ migration_connect_outgoing(s, addr, &local_err);
if (local_err) {
migration_connect_error_propagate(s, error_copy(local_err));
error_propagate(errp, local_err);
- return;
}
}
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 19/25] migration: Move transport connection code into channel.c
2026-01-09 12:40 ` [PATCH v3 19/25] migration: Move transport connection code into channel.c Fabiano Rosas
@ 2026-01-20 9:40 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 9:40 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:13, Fabiano Rosas <farosas@suse.de> wrote:
> (I sorted the includes)
* Could be expunged.
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 66 +++++++++++++++++++++++++++++++++++++++----
> migration/channel.h | 4 +++
> migration/migration.c | 46 ++----------------------------
> 3 files changed, 67 insertions(+), 49 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index f61d30d986..56c80b5cdf 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -12,18 +12,74 @@
>
> #include "qemu/osdep.h"
> #include "channel.h"
> -#include "tls.h"
> +#include "exec.h"
> +#include "fd.h"
> +#include "file.h"
> +#include "io/channel-socket.h"
> +#include "io/channel-tls.h"
> #include "migration.h"
> #include "multifd.h"
> -#include "savevm.h"
> -#include "trace.h"
> #include "options.h"
> +#include "qapi/qapi-types-migration.h"
> #include "qapi/error.h"
> -#include "io/channel-tls.h"
> -#include "io/channel-socket.h"
> +#include "qemu-file.h"
> #include "qemu/yank.h"
> +#include "rdma.h"
> +#include "savevm.h"
> +#include "socket.h"
> +#include "tls.h"
> +#include "trace.h"
> #include "yank_functions.h"
>
> +void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
> + Error **errp)
> +{
> + 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);
> + } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> + 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);
> +#endif
> + } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> + 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);
> + } else {
> + error_setg(errp, "uri is not a valid migration protocol");
> + }
> +}
> +
> +void migration_connect_incoming(MigrationAddress *addr, Error **errp)
> +{
> + 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_incoming(saddr, errp);
> + } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> + fd_connect_incoming(saddr->u.fd.str, errp);
> + }
> +#ifdef CONFIG_RDMA
> + } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
> + rdma_connect_incoming(&addr->u.rdma, errp);
> +#endif
> + } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> + exec_connect_incoming(addr->u.exec.args, errp);
> + } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
> + file_connect_incoming(&addr->u.file, errp);
> + } else {
> + error_setg(errp, "unknown migration protocol");
> + }
> +}
> +
> bool migration_has_main_and_multifd_channels(void)
> {
> MigrationIncomingState *mis = migration_incoming_get_current();
> diff --git a/migration/channel.h b/migration/channel.h
> index 19aa5ab795..8264fe327d 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -17,6 +17,7 @@
> #define QEMU_MIGRATION_CHANNEL_H
>
> #include "io/channel.h"
> +#include "qapi/qapi-types-migration.h"
>
> /* Migration channel types */
> typedef enum {
> @@ -38,4 +39,7 @@ int migration_channel_read_peek(QIOChannel *ioc,
> bool migration_has_main_and_multifd_channels(void);
> bool migration_has_all_channels(void);
>
> +void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
> + Error **errp);
> +void migration_connect_incoming(MigrationAddress *addr, Error **errp);
> #endif
> diff --git a/migration/migration.c b/migration/migration.c
> index aa291f1fed..3c93fb23cc 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -20,13 +20,10 @@
> #include "qemu/main-loop.h"
> #include "migration/blocker.h"
> #include "exec.h"
> -#include "fd.h"
> #include "file.h"
> -#include "socket.h"
> #include "system/runstate.h"
> #include "system/system.h"
> #include "system/cpu-throttle.h"
> -#include "rdma.h"
> #include "ram.h"
> #include "migration/cpr.h"
> #include "migration/global_state.h"
> @@ -783,26 +780,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
> return;
> }
>
> - 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_incoming(saddr, errp);
> - } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> - fd_connect_incoming(saddr->u.fd.str, errp);
> - }
> -#ifdef CONFIG_RDMA
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
> - rdma_connect_incoming(&addr->u.rdma, errp);
> -#endif
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> - exec_connect_incoming(addr->u.exec.args, errp);
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
> - file_connect_incoming(&addr->u.file, errp);
> - } else {
> - error_setg(errp, "unknown migration protocol: %s", uri);
> - }
> + migration_connect_incoming(addr, errp);
>
> /* Close cpr socket to tell source that we are listening */
> cpr_state_close();
> @@ -2234,31 +2212,11 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
> MigrationState *s = migrate_get_current();
> Error *local_err = 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, &local_err);
> - } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
> - fd_connect_outgoing(s, saddr->u.fd.str, &local_err);
> - }
> -#ifdef CONFIG_RDMA
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
> - rdma_connect_outgoing(s, &addr->u.rdma, &local_err);
> -#endif
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
> - exec_connect_outgoing(s, addr->u.exec.args, &local_err);
> - } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
> - file_connect_outgoing(s, &addr->u.file, &local_err);
> - } else {
> - error_setg(&local_err, "uri is not a valid migration protocol");
> - }
> + migration_connect_outgoing(s, addr, &local_err);
>
> if (local_err) {
> migration_connect_error_propagate(s, error_copy(local_err));
> error_propagate(errp, local_err);
> - return;
> }
> }
>
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 20/25] migration: Move channel parsing to channel.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (18 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 19/25] migration: Move transport connection code into channel.c Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 10:15 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 21/25] migration: Move URI " Fabiano Rosas
` (4 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
Encapsulate the MigrationChannelList parsing in a new
migrate_channels_parse() located at channel.c.
This also makes the memory management of the MigrationAddress more
uniform. Previously, half the parsing code (uri parsing) would
allocate memory for the address while the other half (channel parsing)
would instead pass the original QAPI object along. After this patch,
the MigrationAddress is always QAPI_CLONEd, so the callers can use
g_autoptr(MigrationAddress) in all cases.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 45 ++++++++++++++++++++++++++++++++++++++
migration/channel.h | 5 +++++
migration/migration.c | 50 ++++++++++++-------------------------------
3 files changed, 64 insertions(+), 36 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index 56c80b5cdf..8b71b3f430 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "channel.h"
#include "exec.h"
#include "fd.h"
@@ -20,7 +21,9 @@
#include "migration.h"
#include "multifd.h"
#include "options.h"
+#include "qapi/clone-visitor.h"
#include "qapi/qapi-types-migration.h"
+#include "qapi/qapi-visit-migration.h"
#include "qapi/error.h"
#include "qemu-file.h"
#include "qemu/yank.h"
@@ -280,3 +283,45 @@ int migration_channel_read_peek(QIOChannel *ioc,
return 0;
}
+
+bool migrate_channels_parse(MigrationChannelList *channels,
+ MigrationChannel **main_channelp,
+ MigrationChannel **cpr_channelp,
+ Error **errp)
+{
+ MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
+ bool single_channel = cpr_channelp ? false : true;
+
+ if (single_channel && channels->next) {
+ error_setg(errp, "Channel list must have only one entry, "
+ "for type 'main'");
+ return false;
+ }
+
+ for ( ; channels; channels = channels->next) {
+ MigrationChannelType type;
+
+ type = channels->value->channel_type;
+ if (channelv[type]) {
+ error_setg(errp, "Channel list has more than one %s entry",
+ MigrationChannelType_str(type));
+ return false;
+ }
+ channelv[type] = channels->value;
+ }
+
+ if (cpr_channelp) {
+ *cpr_channelp = QAPI_CLONE(MigrationChannel,
+ channelv[MIGRATION_CHANNEL_TYPE_CPR]);
+ }
+
+ *main_channelp = QAPI_CLONE(MigrationChannel,
+ channelv[MIGRATION_CHANNEL_TYPE_MAIN]);
+
+ if (!(*main_channelp)->addr) {
+ error_setg(errp, "Channel list has no main entry");
+ return false;
+ }
+
+ return true;
+}
diff --git a/migration/channel.h b/migration/channel.h
index 8264fe327d..5110fb45a4 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -42,4 +42,9 @@ bool migration_has_all_channels(void);
void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
Error **errp);
void migration_connect_incoming(MigrationAddress *addr, Error **errp);
+
+bool migrate_channels_parse(MigrationChannelList *channels,
+ MigrationChannel **main_channelp,
+ MigrationChannel **cpr_channelp,
+ Error **errp);
#endif
diff --git a/migration/migration.c b/migration/migration.c
index 3c93fb23cc..98c1f38e8e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -741,8 +741,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
MigrationChannelList *channels,
Error **errp)
{
- g_autoptr(MigrationChannel) channel = NULL;
- MigrationAddress *addr = NULL;
+ g_autoptr(MigrationChannel) main_ch = NULL;
MigrationIncomingState *mis = migration_incoming_get_current();
/*
@@ -754,25 +753,20 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
}
if (channels) {
- /* To verify that Migrate channel list has only item */
- if (channels->next) {
- error_setg(errp, "Channel list must have only one entry, "
- "for type 'main'");
+ if (!migrate_channels_parse(channels, &main_ch, NULL, errp)) {
return;
}
- addr = channels->value->addr;
}
if (uri) {
/* caller uses the old URI syntax */
- if (!migrate_uri_parse(uri, &channel, errp)) {
+ if (!migrate_uri_parse(uri, &main_ch, errp)) {
return;
}
- addr = channel->addr;
}
/* transport mechanism not suitable for migration? */
- if (!migration_transport_compatible(addr, errp)) {
+ if (!migration_transport_compatible(main_ch->addr, errp)) {
return;
}
@@ -780,7 +774,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
return;
}
- migration_connect_incoming(addr, errp);
+ migration_connect_incoming(main_ch->addr, errp);
/* Close cpr socket to tell source that we are listening */
cpr_state_close();
@@ -2116,10 +2110,8 @@ void qmp_migrate(const char *uri, bool has_channels,
bool has_resume, bool resume, Error **errp)
{
MigrationState *s = migrate_get_current();
- g_autoptr(MigrationChannel) channel = NULL;
- MigrationAddress *addr = NULL;
- MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
- MigrationChannel *cpr_channel = NULL;
+ g_autoptr(MigrationChannel) main_ch = NULL;
+ g_autoptr(MigrationChannel) cpr_ch = NULL;
/*
* Having preliminary checks for uri and channel
@@ -2130,38 +2122,24 @@ void qmp_migrate(const char *uri, bool has_channels,
}
if (channels) {
- for ( ; channels; channels = channels->next) {
- MigrationChannelType type = channels->value->channel_type;
-
- if (channelv[type]) {
- error_setg(errp, "Channel list has more than one %s entry",
- MigrationChannelType_str(type));
- return;
- }
- channelv[type] = channels->value;
- }
- cpr_channel = channelv[MIGRATION_CHANNEL_TYPE_CPR];
- addr = channelv[MIGRATION_CHANNEL_TYPE_MAIN]->addr;
- if (!addr) {
- error_setg(errp, "Channel list has no main entry");
+ if (!migrate_channels_parse(channels, &main_ch, &cpr_ch, errp)) {
return;
}
}
if (uri) {
/* caller uses the old URI syntax */
- if (!migrate_uri_parse(uri, &channel, errp)) {
+ if (!migrate_uri_parse(uri, &main_ch, errp)) {
return;
}
- addr = channel->addr;
}
/* transport mechanism not suitable for migration? */
- if (!migration_transport_compatible(addr, errp)) {
+ if (!migration_transport_compatible(main_ch->addr, errp)) {
return;
}
- if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
+ if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_ch) {
error_setg(errp, "missing 'cpr' migration channel");
return;
}
@@ -2178,7 +2156,7 @@ void qmp_migrate(const char *uri, bool has_channels,
*/
Error *local_err = NULL;
- if (!cpr_state_save(cpr_channel, &local_err)) {
+ if (!cpr_state_save(cpr_ch, &local_err)) {
goto out;
}
@@ -2194,10 +2172,10 @@ void qmp_migrate(const char *uri, bool has_channels,
*/
if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
- QAPI_CLONE(MigrationAddress, addr));
+ QAPI_CLONE(MigrationAddress, main_ch->addr));
} else {
- qmp_migrate_finish(addr, errp);
+ qmp_migrate_finish(main_ch->addr, errp);
}
out:
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 20/25] migration: Move channel parsing to channel.c
2026-01-09 12:40 ` [PATCH v3 20/25] migration: Move channel parsing to channel.c Fabiano Rosas
@ 2026-01-20 10:15 ` Prasad Pandit
2026-01-20 18:18 ` Fabiano Rosas
0 siblings, 1 reply; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 10:15 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:14, Fabiano Rosas <farosas@suse.de> wrote:
> Encapsulate the MigrationChannelList parsing in a new
> migrate_channels_parse() located at channel.c.
>
> This also makes the memory management of the MigrationAddress more
> uniform. Previously, half the parsing code (uri parsing) would
> allocate memory for the address while the other half (channel parsing)
> would instead pass the original QAPI object along. After this patch,
> the MigrationAddress is always QAPI_CLONEd, so the callers can use
> g_autoptr(MigrationAddress) in all cases.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 45 ++++++++++++++++++++++++++++++++++++++
> migration/channel.h | 5 +++++
> migration/migration.c | 50 ++++++++++++-------------------------------
> 3 files changed, 64 insertions(+), 36 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 56c80b5cdf..8b71b3f430 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -11,6 +11,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "qemu/cutils.h"
> #include "channel.h"
> #include "exec.h"
> #include "fd.h"
> @@ -20,7 +21,9 @@
> #include "migration.h"
> #include "multifd.h"
> #include "options.h"
> +#include "qapi/clone-visitor.h"
> #include "qapi/qapi-types-migration.h"
> +#include "qapi/qapi-visit-migration.h"
> #include "qapi/error.h"
> #include "qemu-file.h"
> #include "qemu/yank.h"
> @@ -280,3 +283,45 @@ int migration_channel_read_peek(QIOChannel *ioc,
>
> return 0;
> }
> +
> +bool migrate_channels_parse(MigrationChannelList *channels,
> + MigrationChannel **main_channelp,
> + MigrationChannel **cpr_channelp,
> + Error **errp)
> +{
> + MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
> + bool single_channel = cpr_channelp ? false : true;
> +
> + if (single_channel && channels->next) {
> + error_setg(errp, "Channel list must have only one entry, "
> + "for type 'main'");
> + return false;
> + }
* Instead of the single_channel variable above, we could say
(!cpr_channelp && channels->next)? and avoid the single_channel
variable.
> + for ( ; channels; channels = channels->next) {
> + MigrationChannelType type;
> +
> + type = channels->value->channel_type;
> + if (channelv[type]) {
> + error_setg(errp, "Channel list has more than one %s entry",
> + MigrationChannelType_str(type));
> + return false;
> + }
> + channelv[type] = channels->value;
> + }
> +
> + if (cpr_channelp) {
> + *cpr_channelp = QAPI_CLONE(MigrationChannel,
> + channelv[MIGRATION_CHANNEL_TYPE_CPR]);
> + }
> +
> + *main_channelp = QAPI_CLONE(MigrationChannel,
> + channelv[MIGRATION_CHANNEL_TYPE_MAIN]);
> +
> + if (!(*main_channelp)->addr) {
> + error_setg(errp, "Channel list has no main entry");
> + return false;
> + }
> +
> + return true;
> +}
> diff --git a/migration/channel.h b/migration/channel.h
> index 8264fe327d..5110fb45a4 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -42,4 +42,9 @@ bool migration_has_all_channels(void);
> void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
> Error **errp);
> void migration_connect_incoming(MigrationAddress *addr, Error **errp);
> +
> +bool migrate_channels_parse(MigrationChannelList *channels,
> + MigrationChannel **main_channelp,
> + MigrationChannel **cpr_channelp,
> + Error **errp);
> #endif
> diff --git a/migration/migration.c b/migration/migration.c
> index 3c93fb23cc..98c1f38e8e 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -741,8 +741,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
> MigrationChannelList *channels,
> Error **errp)
> {
> - g_autoptr(MigrationChannel) channel = NULL;
> - MigrationAddress *addr = NULL;
> + g_autoptr(MigrationChannel) main_ch = NULL;
> MigrationIncomingState *mis = migration_incoming_get_current();
>
> /*
> @@ -754,25 +753,20 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
> }
>
> if (channels) {
> - /* To verify that Migrate channel list has only item */
> - if (channels->next) {
> - error_setg(errp, "Channel list must have only one entry, "
> - "for type 'main'");
> + if (!migrate_channels_parse(channels, &main_ch, NULL, errp)) {
> return;
> }
> - addr = channels->value->addr;
> }
>
> if (uri) {
> /* caller uses the old URI syntax */
> - if (!migrate_uri_parse(uri, &channel, errp)) {
> + if (!migrate_uri_parse(uri, &main_ch, errp)) {
> return;
> }
> - addr = channel->addr;
> }
>
> /* transport mechanism not suitable for migration? */
> - if (!migration_transport_compatible(addr, errp)) {
> + if (!migration_transport_compatible(main_ch->addr, errp)) {
> return;
> }
>
> @@ -780,7 +774,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
> return;
> }
>
> - migration_connect_incoming(addr, errp);
> + migration_connect_incoming(main_ch->addr, errp);
>
> /* Close cpr socket to tell source that we are listening */
> cpr_state_close();
> @@ -2116,10 +2110,8 @@ void qmp_migrate(const char *uri, bool has_channels,
> bool has_resume, bool resume, Error **errp)
> {
> MigrationState *s = migrate_get_current();
> - g_autoptr(MigrationChannel) channel = NULL;
> - MigrationAddress *addr = NULL;
> - MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
> - MigrationChannel *cpr_channel = NULL;
> + g_autoptr(MigrationChannel) main_ch = NULL;
> + g_autoptr(MigrationChannel) cpr_ch = NULL;
>
> /*
> * Having preliminary checks for uri and channel
> @@ -2130,38 +2122,24 @@ void qmp_migrate(const char *uri, bool has_channels,
> }
>
> if (channels) {
> - for ( ; channels; channels = channels->next) {
> - MigrationChannelType type = channels->value->channel_type;
> -
> - if (channelv[type]) {
> - error_setg(errp, "Channel list has more than one %s entry",
> - MigrationChannelType_str(type));
> - return;
> - }
> - channelv[type] = channels->value;
> - }
> - cpr_channel = channelv[MIGRATION_CHANNEL_TYPE_CPR];
> - addr = channelv[MIGRATION_CHANNEL_TYPE_MAIN]->addr;
> - if (!addr) {
> - error_setg(errp, "Channel list has no main entry");
> + if (!migrate_channels_parse(channels, &main_ch, &cpr_ch, errp)) {
> return;
> }
> }
>
> if (uri) {
> /* caller uses the old URI syntax */
> - if (!migrate_uri_parse(uri, &channel, errp)) {
> + if (!migrate_uri_parse(uri, &main_ch, errp)) {
> return;
> }
> - addr = channel->addr;
> }
>
> /* transport mechanism not suitable for migration? */
> - if (!migration_transport_compatible(addr, errp)) {
> + if (!migration_transport_compatible(main_ch->addr, errp)) {
> return;
> }
>
> - if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_ch) {
> error_setg(errp, "missing 'cpr' migration channel");
> return;
> }
* This check for (_CPR_TRANSFER && !cpr_ch) and error could be moved
to migrate_channels_parse() as is done for the main_ch.
> @@ -2178,7 +2156,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> */
> Error *local_err = NULL;
>
> - if (!cpr_state_save(cpr_channel, &local_err)) {
> + if (!cpr_state_save(cpr_ch, &local_err)) {
> goto out;
> }
>
> @@ -2194,10 +2172,10 @@ void qmp_migrate(const char *uri, bool has_channels,
> */
> if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
> migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
> - QAPI_CLONE(MigrationAddress, addr));
> + QAPI_CLONE(MigrationAddress, main_ch->addr));
>
> } else {
> - qmp_migrate_finish(addr, errp);
> + qmp_migrate_finish(main_ch->addr, errp);
> }
>
> out:
> --
* Otherwise it looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH v3 20/25] migration: Move channel parsing to channel.c
2026-01-20 10:15 ` Prasad Pandit
@ 2026-01-20 18:18 ` Fabiano Rosas
0 siblings, 0 replies; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-20 18:18 UTC (permalink / raw)
To: Prasad Pandit; +Cc: qemu-devel, peterx, berrange
Prasad Pandit <ppandit@redhat.com> writes:
> On Fri, 9 Jan 2026 at 18:14, Fabiano Rosas <farosas@suse.de> wrote:
>> Encapsulate the MigrationChannelList parsing in a new
>> migrate_channels_parse() located at channel.c.
>>
>> This also makes the memory management of the MigrationAddress more
>> uniform. Previously, half the parsing code (uri parsing) would
>> allocate memory for the address while the other half (channel parsing)
>> would instead pass the original QAPI object along. After this patch,
>> the MigrationAddress is always QAPI_CLONEd, so the callers can use
>> g_autoptr(MigrationAddress) in all cases.
>>
>> Reviewed-by: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>> ---
>> migration/channel.c | 45 ++++++++++++++++++++++++++++++++++++++
>> migration/channel.h | 5 +++++
>> migration/migration.c | 50 ++++++++++++-------------------------------
>> 3 files changed, 64 insertions(+), 36 deletions(-)
>>
>> diff --git a/migration/channel.c b/migration/channel.c
>> index 56c80b5cdf..8b71b3f430 100644
>> --- a/migration/channel.c
>> +++ b/migration/channel.c
>> @@ -11,6 +11,7 @@
>> */
>>
>> #include "qemu/osdep.h"
>> +#include "qemu/cutils.h"
>> #include "channel.h"
>> #include "exec.h"
>> #include "fd.h"
>> @@ -20,7 +21,9 @@
>> #include "migration.h"
>> #include "multifd.h"
>> #include "options.h"
>> +#include "qapi/clone-visitor.h"
>> #include "qapi/qapi-types-migration.h"
>> +#include "qapi/qapi-visit-migration.h"
>> #include "qapi/error.h"
>> #include "qemu-file.h"
>> #include "qemu/yank.h"
>> @@ -280,3 +283,45 @@ int migration_channel_read_peek(QIOChannel *ioc,
>>
>> return 0;
>> }
>> +
>> +bool migrate_channels_parse(MigrationChannelList *channels,
>> + MigrationChannel **main_channelp,
>> + MigrationChannel **cpr_channelp,
>> + Error **errp)
>> +{
>> + MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
>> + bool single_channel = cpr_channelp ? false : true;
>> +
>> + if (single_channel && channels->next) {
>> + error_setg(errp, "Channel list must have only one entry, "
>> + "for type 'main'");
>> + return false;
>> + }
>
> * Instead of the single_channel variable above, we could say
> (!cpr_channelp && channels->next)? and avoid the single_channel
> variable.
>
ok
>> + for ( ; channels; channels = channels->next) {
>> + MigrationChannelType type;
>> +
>> + type = channels->value->channel_type;
>> + if (channelv[type]) {
>> + error_setg(errp, "Channel list has more than one %s entry",
>> + MigrationChannelType_str(type));
>> + return false;
>> + }
>> + channelv[type] = channels->value;
>> + }
>> +
>> + if (cpr_channelp) {
>> + *cpr_channelp = QAPI_CLONE(MigrationChannel,
>> + channelv[MIGRATION_CHANNEL_TYPE_CPR]);
>> + }
>> +
>> + *main_channelp = QAPI_CLONE(MigrationChannel,
>> + channelv[MIGRATION_CHANNEL_TYPE_MAIN]);
>> +
>> + if (!(*main_channelp)->addr) {
>> + error_setg(errp, "Channel list has no main entry");
>> + return false;
>> + }
>> +
>> + return true;
>> +}
>> diff --git a/migration/channel.h b/migration/channel.h
>> index 8264fe327d..5110fb45a4 100644
>> --- a/migration/channel.h
>> +++ b/migration/channel.h
>> @@ -42,4 +42,9 @@ bool migration_has_all_channels(void);
>> void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
>> Error **errp);
>> void migration_connect_incoming(MigrationAddress *addr, Error **errp);
>> +
>> +bool migrate_channels_parse(MigrationChannelList *channels,
>> + MigrationChannel **main_channelp,
>> + MigrationChannel **cpr_channelp,
>> + Error **errp);
>> #endif
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 3c93fb23cc..98c1f38e8e 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -741,8 +741,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
>> MigrationChannelList *channels,
>> Error **errp)
>> {
>> - g_autoptr(MigrationChannel) channel = NULL;
>> - MigrationAddress *addr = NULL;
>> + g_autoptr(MigrationChannel) main_ch = NULL;
>> MigrationIncomingState *mis = migration_incoming_get_current();
>>
>> /*
>> @@ -754,25 +753,20 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
>> }
>>
>> if (channels) {
>> - /* To verify that Migrate channel list has only item */
>> - if (channels->next) {
>> - error_setg(errp, "Channel list must have only one entry, "
>> - "for type 'main'");
>> + if (!migrate_channels_parse(channels, &main_ch, NULL, errp)) {
>> return;
>> }
>> - addr = channels->value->addr;
>> }
>>
>> if (uri) {
>> /* caller uses the old URI syntax */
>> - if (!migrate_uri_parse(uri, &channel, errp)) {
>> + if (!migrate_uri_parse(uri, &main_ch, errp)) {
>> return;
>> }
>> - addr = channel->addr;
>> }
>>
>> /* transport mechanism not suitable for migration? */
>> - if (!migration_transport_compatible(addr, errp)) {
>> + if (!migration_transport_compatible(main_ch->addr, errp)) {
>> return;
>> }
>>
>> @@ -780,7 +774,7 @@ static void qemu_setup_incoming_migration(const char *uri, bool has_channels,
>> return;
>> }
>>
>> - migration_connect_incoming(addr, errp);
>> + migration_connect_incoming(main_ch->addr, errp);
>>
>> /* Close cpr socket to tell source that we are listening */
>> cpr_state_close();
>> @@ -2116,10 +2110,8 @@ void qmp_migrate(const char *uri, bool has_channels,
>> bool has_resume, bool resume, Error **errp)
>> {
>> MigrationState *s = migrate_get_current();
>> - g_autoptr(MigrationChannel) channel = NULL;
>> - MigrationAddress *addr = NULL;
>> - MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL };
>> - MigrationChannel *cpr_channel = NULL;
>> + g_autoptr(MigrationChannel) main_ch = NULL;
>> + g_autoptr(MigrationChannel) cpr_ch = NULL;
>>
>> /*
>> * Having preliminary checks for uri and channel
>> @@ -2130,38 +2122,24 @@ void qmp_migrate(const char *uri, bool has_channels,
>> }
>>
>> if (channels) {
>> - for ( ; channels; channels = channels->next) {
>> - MigrationChannelType type = channels->value->channel_type;
>> -
>> - if (channelv[type]) {
>> - error_setg(errp, "Channel list has more than one %s entry",
>> - MigrationChannelType_str(type));
>> - return;
>> - }
>> - channelv[type] = channels->value;
>> - }
>> - cpr_channel = channelv[MIGRATION_CHANNEL_TYPE_CPR];
>> - addr = channelv[MIGRATION_CHANNEL_TYPE_MAIN]->addr;
>> - if (!addr) {
>> - error_setg(errp, "Channel list has no main entry");
>> + if (!migrate_channels_parse(channels, &main_ch, &cpr_ch, errp)) {
>> return;
>> }
>> }
>>
>> if (uri) {
>> /* caller uses the old URI syntax */
>> - if (!migrate_uri_parse(uri, &channel, errp)) {
>> + if (!migrate_uri_parse(uri, &main_ch, errp)) {
>> return;
>> }
>> - addr = channel->addr;
>> }
>>
>> /* transport mechanism not suitable for migration? */
>> - if (!migration_transport_compatible(addr, errp)) {
>> + if (!migration_transport_compatible(main_ch->addr, errp)) {
>> return;
>> }
>>
>> - if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_channel) {
>> + if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !cpr_ch) {
>> error_setg(errp, "missing 'cpr' migration channel");
>> return;
>> }
>
> * This check for (_CPR_TRANSFER && !cpr_ch) and error could be moved
> to migrate_channels_parse() as is done for the main_ch.
>
Hm, it would then apply to the incoming side as well which can't set the
mode due to how cpr-transfer works. But I guess it's fine as the
invocation of migration_channel_parse_input is already different between
src and dst. I'll change it. Thanks
>> @@ -2178,7 +2156,7 @@ void qmp_migrate(const char *uri, bool has_channels,
>> */
>> Error *local_err = NULL;
>>
>> - if (!cpr_state_save(cpr_channel, &local_err)) {
>> + if (!cpr_state_save(cpr_ch, &local_err)) {
>> goto out;
>> }
>>
>> @@ -2194,10 +2172,10 @@ void qmp_migrate(const char *uri, bool has_channels,
>> */
>> if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
>> migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
>> - QAPI_CLONE(MigrationAddress, addr));
>> + QAPI_CLONE(MigrationAddress, main_ch->addr));
>>
>> } else {
>> - qmp_migrate_finish(addr, errp);
>> + qmp_migrate_finish(main_ch->addr, errp);
>> }
>>
>> out:
>> --
>
> * Otherwise it looks okay.
> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
>
> Thank you.
> ---
> - Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 21/25] migration: Move URI parsing to channel.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (19 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 20/25] migration: Move channel parsing to channel.c Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 10:20 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 22/25] migration: Free cpr-transfer MigrationAddress along with gsource Fabiano Rosas
` (3 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
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.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 82 +++++++++++++++++++++++++++++++++++--
migration/channel.h | 9 ++--
migration/migration.c | 95 ++-----------------------------------------
3 files changed, 86 insertions(+), 100 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index 8b71b3f430..cee78532ea 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -284,10 +284,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 = cpr_channelp ? false : true;
@@ -325,3 +325,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 5110fb45a4..a7d0d29058 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -43,8 +43,9 @@ void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
Error **errp);
void migration_connect_incoming(MigrationAddress *addr, Error **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 98c1f38e8e..52c1bb5da2 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;
@@ -2113,27 +2040,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
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 21/25] migration: Move URI parsing to channel.c
2026-01-09 12:40 ` [PATCH v3 21/25] migration: Move URI " Fabiano Rosas
@ 2026-01-20 10:20 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 10:20 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:16, Fabiano Rosas <farosas@suse.de> 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.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 82 +++++++++++++++++++++++++++++++++++--
> migration/channel.h | 9 ++--
> migration/migration.c | 95 ++-----------------------------------------
> 3 files changed, 86 insertions(+), 100 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index 8b71b3f430..cee78532ea 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -284,10 +284,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 = cpr_channelp ? false : true;
> @@ -325,3 +325,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 5110fb45a4..a7d0d29058 100644
> --- a/migration/channel.h
> +++ b/migration/channel.h
> @@ -43,8 +43,9 @@ void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr,
> Error **errp);
> void migration_connect_incoming(MigrationAddress *addr, Error **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 98c1f38e8e..52c1bb5da2 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;
> @@ -2113,27 +2040,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;
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 22/25] migration: Free cpr-transfer MigrationAddress along with gsource
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (20 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 21/25] migration: Move URI " Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:17 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 23/25] migration: Move CPR HUP watch to cpr-transfer.c Fabiano Rosas
` (2 subsequent siblings)
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Mark Kanda, Ben Chaney
When setting a callback on a Glib source and giving it a data pointer,
it's natural to also provide the destructor for the data in question.
Since migrate_hup_add() already needs to clone the MigrationAddress
when setting the qmp_migrate_finish_cb callback, also pass the
qapi_free_MigrationAddress as the GDestroyNotify callback.
With this the address doesn't need to be freed at the callback body,
making the management of that memory slight simpler.
(also fix the indentation of migrate_hup_add)
Cc: Mark Kanda <mark.kanda@oracle.com>
Cc: Ben Chaney <bchaney@akamai.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 52c1bb5da2..5167233f76 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2007,9 +2007,11 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
void *opaque)
{
- s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
- g_source_set_callback(s->hup_source, cb, opaque, NULL);
- g_source_attach(s->hup_source, NULL);
+ s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
+ g_source_set_callback(s->hup_source, cb,
+ QAPI_CLONE(MigrationAddress, opaque),
+ (GDestroyNotify)qapi_free_MigrationAddress);
+ g_source_attach(s->hup_source, NULL);
}
static void migrate_hup_delete(MigrationState *s)
@@ -2028,7 +2030,6 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
MigrationAddress *addr = opaque;
qmp_migrate_finish(addr, NULL);
- qapi_free_MigrationAddress(addr);
return G_SOURCE_REMOVE;
}
@@ -2083,7 +2084,7 @@ void qmp_migrate(const char *uri, bool has_channels,
*/
if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
- QAPI_CLONE(MigrationAddress, main_ch->addr));
+ main_ch->addr);
} else {
qmp_migrate_finish(main_ch->addr, errp);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 22/25] migration: Free cpr-transfer MigrationAddress along with gsource
2026-01-09 12:40 ` [PATCH v3 22/25] migration: Free cpr-transfer MigrationAddress along with gsource Fabiano Rosas
@ 2026-01-20 11:17 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:17 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Mark Kanda, Ben Chaney
On Fri, 9 Jan 2026 at 18:19, Fabiano Rosas <farosas@suse.de> wrote:
> When setting a callback on a Glib source and giving it a data pointer,
> it's natural to also provide the destructor for the data in question.
>
> Since migrate_hup_add() already needs to clone the MigrationAddress
> when setting the qmp_migrate_finish_cb callback, also pass the
> qapi_free_MigrationAddress as the GDestroyNotify callback.
>
> With this the address doesn't need to be freed at the callback body,
> making the management of that memory slight simpler.
* slight -> slightly OR just skip it. -> ... memory simpler.
> (also fix the indentation of migrate_hup_add)
* This note could be purged.
> Cc: Mark Kanda <mark.kanda@oracle.com>
> Cc: Ben Chaney <bchaney@akamai.com>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 52c1bb5da2..5167233f76 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2007,9 +2007,11 @@ static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
> static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
> void *opaque)
> {
> - s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
> - g_source_set_callback(s->hup_source, cb, opaque, NULL);
> - g_source_attach(s->hup_source, NULL);
> + s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
> + g_source_set_callback(s->hup_source, cb,
> + QAPI_CLONE(MigrationAddress, opaque),
> + (GDestroyNotify)qapi_free_MigrationAddress);
> + g_source_attach(s->hup_source, NULL);
> }
>
> static void migrate_hup_delete(MigrationState *s)
> @@ -2028,7 +2030,6 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> MigrationAddress *addr = opaque;
>
> qmp_migrate_finish(addr, NULL);
> - qapi_free_MigrationAddress(addr);
> return G_SOURCE_REMOVE;
> }
>
> @@ -2083,7 +2084,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> */
> if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
> migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
> - QAPI_CLONE(MigrationAddress, main_ch->addr));
> + main_ch->addr);
>
> } else {
> qmp_migrate_finish(main_ch->addr, errp);
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 23/25] migration: Move CPR HUP watch to cpr-transfer.c
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (21 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 22/25] migration: Free cpr-transfer MigrationAddress along with gsource Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:24 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 24/25] migration: Remove qmp_migrate_finish Fabiano Rosas
2026-01-09 12:40 ` [PATCH v3 25/25] migration/channel: Centralize calling migration_channel_connect_outgoing Fabiano Rosas
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Mark Kanda, Ben Chaney
Move this CPR-specific code into a cpr file. While here, give the
functions more significant names.
This makes the new idea (after cpr-transfer) of having two parts to
qmp_migrate slightly more obvious: either wait for the hangup or
continue directly.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
include/migration/cpr.h | 5 +++++
migration/cpr-transfer.c | 23 +++++++++++++++++++++++
migration/migration.c | 27 +++------------------------
3 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/include/migration/cpr.h b/include/migration/cpr.h
index 027cb98073..5850fd1788 100644
--- a/include/migration/cpr.h
+++ b/include/migration/cpr.h
@@ -9,6 +9,7 @@
#define MIGRATION_CPR_H
#include "qapi/qapi-types-migration.h"
+#include "io/channel.h"
#include "qemu/queue.h"
#define MIG_MODE_NONE -1
@@ -53,6 +54,10 @@ int cpr_get_fd_param(const char *name, const char *fdname, int index,
QEMUFile *cpr_transfer_output(MigrationChannel *channel, Error **errp);
QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp);
+void cpr_transfer_add_hup_watch(MigrationState *s, QIOChannelFunc func,
+ void *opaque);
+void cpr_transfer_source_destroy(MigrationState *s);
+
void cpr_exec_init(void);
QEMUFile *cpr_exec_output(Error **errp);
QEMUFile *cpr_exec_input(Error **errp);
diff --git a/migration/cpr-transfer.c b/migration/cpr-transfer.c
index 00371d17c3..61d5c9dce2 100644
--- a/migration/cpr-transfer.c
+++ b/migration/cpr-transfer.c
@@ -6,7 +6,10 @@
*/
#include "qemu/osdep.h"
+#include "qapi/clone-visitor.h"
#include "qapi/error.h"
+#include "qapi/qapi-visit-migration.h"
+#include "io/channel.h"
#include "io/channel-file.h"
#include "io/channel-socket.h"
#include "io/net-listener.h"
@@ -72,3 +75,23 @@ QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp)
return NULL;
}
}
+
+void cpr_transfer_add_hup_watch(MigrationState *s, QIOChannelFunc func,
+ void *opaque)
+{
+ s->hup_source = qio_channel_create_watch(cpr_state_ioc(), G_IO_HUP);
+ g_source_set_callback(s->hup_source,
+ (GSourceFunc)func,
+ QAPI_CLONE(MigrationAddress, opaque),
+ (GDestroyNotify)qapi_free_MigrationAddress);
+ g_source_attach(s->hup_source, NULL);
+}
+
+void cpr_transfer_source_destroy(MigrationState *s)
+{
+ if (s->hup_source) {
+ g_source_destroy(s->hup_source);
+ g_source_unref(s->hup_source);
+ s->hup_source = NULL;
+ }
+}
diff --git a/migration/migration.c b/migration/migration.c
index 5167233f76..6be2849326 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -100,7 +100,6 @@ static bool migration_object_check(MigrationState *ms, Error **errp);
static bool migration_switchover_start(MigrationState *s, Error **errp);
static bool close_return_path_on_source(MigrationState *s);
static void migration_completion_end(MigrationState *s);
-static void migrate_hup_delete(MigrationState *s);
static void migration_downtime_start(MigrationState *s)
{
@@ -1297,7 +1296,7 @@ static void migration_cleanup(MigrationState *s)
qemu_savevm_state_cleanup();
cpr_state_close();
- migrate_hup_delete(s);
+ cpr_transfer_source_destroy(s);
close_return_path_on_source(s);
@@ -1480,7 +1479,7 @@ void migration_cancel(void)
migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
MIGRATION_STATUS_CANCELLED);
cpr_state_close();
- migrate_hup_delete(s);
+ cpr_transfer_source_destroy(s);
}
}
@@ -2004,25 +2003,6 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
-static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
- void *opaque)
-{
- s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
- g_source_set_callback(s->hup_source, cb,
- QAPI_CLONE(MigrationAddress, opaque),
- (GDestroyNotify)qapi_free_MigrationAddress);
- g_source_attach(s->hup_source, NULL);
-}
-
-static void migrate_hup_delete(MigrationState *s)
-{
- if (s->hup_source) {
- g_source_destroy(s->hup_source);
- g_source_unref(s->hup_source);
- s->hup_source = NULL;
- }
-}
-
static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
GIOCondition cond,
void *opaque)
@@ -2083,8 +2063,7 @@ void qmp_migrate(const char *uri, bool has_channels,
* connection, so qmp_migrate_finish will fail to connect, and then recover.
*/
if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
- migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
- main_ch->addr);
+ cpr_transfer_add_hup_watch(s, qmp_migrate_finish_cb, main_ch->addr);
} else {
qmp_migrate_finish(main_ch->addr, errp);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 23/25] migration: Move CPR HUP watch to cpr-transfer.c
2026-01-09 12:40 ` [PATCH v3 23/25] migration: Move CPR HUP watch to cpr-transfer.c Fabiano Rosas
@ 2026-01-20 11:24 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:24 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Mark Kanda, Ben Chaney
On Fri, 9 Jan 2026 at 18:19, Fabiano Rosas <farosas@suse.de> wrote:
> Move this CPR-specific code into a cpr file. While here, give the
> functions more significant names.
>
> This makes the new idea (after cpr-transfer) of having two parts to
> qmp_migrate slightly more obvious: either wait for the hangup or
> continue directly.
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> include/migration/cpr.h | 5 +++++
> migration/cpr-transfer.c | 23 +++++++++++++++++++++++
> migration/migration.c | 27 +++------------------------
> 3 files changed, 31 insertions(+), 24 deletions(-)
>
> diff --git a/include/migration/cpr.h b/include/migration/cpr.h
> index 027cb98073..5850fd1788 100644
> --- a/include/migration/cpr.h
> +++ b/include/migration/cpr.h
> @@ -9,6 +9,7 @@
> #define MIGRATION_CPR_H
>
> #include "qapi/qapi-types-migration.h"
> +#include "io/channel.h"
> #include "qemu/queue.h"
>
> #define MIG_MODE_NONE -1
> @@ -53,6 +54,10 @@ int cpr_get_fd_param(const char *name, const char *fdname, int index,
> QEMUFile *cpr_transfer_output(MigrationChannel *channel, Error **errp);
> QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp);
>
> +void cpr_transfer_add_hup_watch(MigrationState *s, QIOChannelFunc func,
> + void *opaque);
> +void cpr_transfer_source_destroy(MigrationState *s);
> +
> void cpr_exec_init(void);
> QEMUFile *cpr_exec_output(Error **errp);
> QEMUFile *cpr_exec_input(Error **errp);
> diff --git a/migration/cpr-transfer.c b/migration/cpr-transfer.c
> index 00371d17c3..61d5c9dce2 100644
> --- a/migration/cpr-transfer.c
> +++ b/migration/cpr-transfer.c
> @@ -6,7 +6,10 @@
> */
>
> #include "qemu/osdep.h"
> +#include "qapi/clone-visitor.h"
> #include "qapi/error.h"
> +#include "qapi/qapi-visit-migration.h"
> +#include "io/channel.h"
> #include "io/channel-file.h"
> #include "io/channel-socket.h"
> #include "io/net-listener.h"
> @@ -72,3 +75,23 @@ QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp)
> return NULL;
> }
> }
> +
> +void cpr_transfer_add_hup_watch(MigrationState *s, QIOChannelFunc func,
> + void *opaque)
> +{
> + s->hup_source = qio_channel_create_watch(cpr_state_ioc(), G_IO_HUP);
> + g_source_set_callback(s->hup_source,
> + (GSourceFunc)func,
> + QAPI_CLONE(MigrationAddress, opaque),
> + (GDestroyNotify)qapi_free_MigrationAddress);
> + g_source_attach(s->hup_source, NULL);
> +}
> +
> +void cpr_transfer_source_destroy(MigrationState *s)
> +{
> + if (s->hup_source) {
> + g_source_destroy(s->hup_source);
> + g_source_unref(s->hup_source);
> + s->hup_source = NULL;
> + }
> +}
> diff --git a/migration/migration.c b/migration/migration.c
> index 5167233f76..6be2849326 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -100,7 +100,6 @@ static bool migration_object_check(MigrationState *ms, Error **errp);
> static bool migration_switchover_start(MigrationState *s, Error **errp);
> static bool close_return_path_on_source(MigrationState *s);
> static void migration_completion_end(MigrationState *s);
> -static void migrate_hup_delete(MigrationState *s);
>
> static void migration_downtime_start(MigrationState *s)
> {
> @@ -1297,7 +1296,7 @@ static void migration_cleanup(MigrationState *s)
>
> qemu_savevm_state_cleanup();
> cpr_state_close();
> - migrate_hup_delete(s);
> + cpr_transfer_source_destroy(s);
>
> close_return_path_on_source(s);
>
> @@ -1480,7 +1479,7 @@ void migration_cancel(void)
> migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
> MIGRATION_STATUS_CANCELLED);
> cpr_state_close();
> - migrate_hup_delete(s);
> + cpr_transfer_source_destroy(s);
> }
> }
>
> @@ -2004,25 +2003,6 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
>
> static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
>
> -static void migrate_hup_add(MigrationState *s, QIOChannel *ioc, GSourceFunc cb,
> - void *opaque)
> -{
> - s->hup_source = qio_channel_create_watch(ioc, G_IO_HUP);
> - g_source_set_callback(s->hup_source, cb,
> - QAPI_CLONE(MigrationAddress, opaque),
> - (GDestroyNotify)qapi_free_MigrationAddress);
> - g_source_attach(s->hup_source, NULL);
> -}
> -
> -static void migrate_hup_delete(MigrationState *s)
> -{
> - if (s->hup_source) {
> - g_source_destroy(s->hup_source);
> - g_source_unref(s->hup_source);
> - s->hup_source = NULL;
> - }
> -}
> -
> static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> GIOCondition cond,
> void *opaque)
> @@ -2083,8 +2063,7 @@ void qmp_migrate(const char *uri, bool has_channels,
> * connection, so qmp_migrate_finish will fail to connect, and then recover.
> */
> if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
> - migrate_hup_add(s, cpr_state_ioc(), (GSourceFunc)qmp_migrate_finish_cb,
> - main_ch->addr);
> + cpr_transfer_add_hup_watch(s, qmp_migrate_finish_cb, main_ch->addr);
>
> } else {
> qmp_migrate_finish(main_ch->addr, errp);
> --
* Looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 24/25] migration: Remove qmp_migrate_finish
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (22 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 23/25] migration: Move CPR HUP watch to cpr-transfer.c Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-20 11:07 ` Prasad Pandit
2026-01-09 12:40 ` [PATCH v3 25/25] migration/channel: Centralize calling migration_channel_connect_outgoing Fabiano Rosas
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange
After cleanups, the qmp_migrate_finish function is now just a call to
migration_connect_outgoing(). Remove qmp_migrate_finish() and rename
the qmp_migrate_finish_cb callback.
This also allows the function's error handling to be removed as it now
receives &local_err like the rest of the callees of qmp_migrate().
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 35 +++++++++++++----------------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 6be2849326..086bbb03de 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2001,15 +2001,18 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
return true;
}
-static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
-
-static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
- GIOCondition cond,
- void *opaque)
+static gboolean migration_connect_outgoing_cb(QIOChannel *channel,
+ GIOCondition cond, void *opaque)
{
- MigrationAddress *addr = opaque;
+ MigrationState *s = migrate_get_current();
+ Error *local_err = NULL;
+
+ migration_connect_outgoing(s, opaque, &local_err);
+
+ if (local_err) {
+ migration_connect_error_propagate(s, local_err);
+ }
- qmp_migrate_finish(addr, NULL);
return G_SOURCE_REMOVE;
}
@@ -2063,10 +2066,11 @@ void qmp_migrate(const char *uri, bool has_channels,
* connection, so qmp_migrate_finish will fail to connect, and then recover.
*/
if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
- cpr_transfer_add_hup_watch(s, qmp_migrate_finish_cb, main_ch->addr);
+ cpr_transfer_add_hup_watch(s, migration_connect_outgoing_cb,
+ main_ch->addr);
} else {
- qmp_migrate_finish(main_ch->addr, errp);
+ migration_connect_outgoing(s, main_ch->addr, &local_err);
}
out:
@@ -2076,19 +2080,6 @@ out:
}
}
-static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
-{
- MigrationState *s = migrate_get_current();
- Error *local_err = NULL;
-
- migration_connect_outgoing(s, addr, &local_err);
-
- if (local_err) {
- migration_connect_error_propagate(s, error_copy(local_err));
- error_propagate(errp, local_err);
- }
-}
-
void qmp_migrate_cancel(Error **errp)
{
/*
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 24/25] migration: Remove qmp_migrate_finish
2026-01-09 12:40 ` [PATCH v3 24/25] migration: Remove qmp_migrate_finish Fabiano Rosas
@ 2026-01-20 11:07 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-20 11:07 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange
On Fri, 9 Jan 2026 at 18:18, Fabiano Rosas <farosas@suse.de> wrote:
> After cleanups, the qmp_migrate_finish function is now just a call to
> migration_connect_outgoing(). Remove qmp_migrate_finish() and rename
> the qmp_migrate_finish_cb callback.
>
> This also allows the function's error handling to be removed as it now
> receives &local_err like the rest of the callees of qmp_migrate().
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/migration.c | 35 +++++++++++++----------------------
> 1 file changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/migration/migration.c b/migration/migration.c
> index 6be2849326..086bbb03de 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2001,15 +2001,18 @@ static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
> return true;
> }
>
> -static void qmp_migrate_finish(MigrationAddress *addr, Error **errp);
> -
> -static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> - GIOCondition cond,
> - void *opaque)
> +static gboolean migration_connect_outgoing_cb(QIOChannel *channel,
> + GIOCondition cond, void *opaque)
> {
> - MigrationAddress *addr = opaque;
> + MigrationState *s = migrate_get_current();
> + Error *local_err = NULL;
> +
> + migration_connect_outgoing(s, opaque, &local_err);
> +
> + if (local_err) {
> + migration_connect_error_propagate(s, local_err);
> + }
>
> - qmp_migrate_finish(addr, NULL);
> return G_SOURCE_REMOVE;
> }
>
> @@ -2063,10 +2066,11 @@ void qmp_migrate(const char *uri, bool has_channels,
> * connection, so qmp_migrate_finish will fail to connect, and then recover.
> */
> if (migrate_mode() == MIG_MODE_CPR_TRANSFER) {
> - cpr_transfer_add_hup_watch(s, qmp_migrate_finish_cb, main_ch->addr);
> + cpr_transfer_add_hup_watch(s, migration_connect_outgoing_cb,
> + main_ch->addr);
>
> } else {
> - qmp_migrate_finish(main_ch->addr, errp);
> + migration_connect_outgoing(s, main_ch->addr, &local_err);
> }
>
> out:
> @@ -2076,19 +2080,6 @@ out:
> }
> }
>
> -static void qmp_migrate_finish(MigrationAddress *addr, Error **errp)
> -{
> - MigrationState *s = migrate_get_current();
> - Error *local_err = NULL;
> -
> - migration_connect_outgoing(s, addr, &local_err);
> -
> - if (local_err) {
> - migration_connect_error_propagate(s, error_copy(local_err));
> - error_propagate(errp, local_err);
> - }
> -}
> -
> void qmp_migrate_cancel(Error **errp)
> {
> /*
> --
* Nice. Looks good.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v3 25/25] migration/channel: Centralize calling migration_channel_connect_outgoing
2026-01-09 12:40 [PATCH v3 00/25] migration: Cleanup early connection code Fabiano Rosas
` (23 preceding siblings ...)
2026-01-09 12:40 ` [PATCH v3 24/25] migration: Remove qmp_migrate_finish Fabiano Rosas
@ 2026-01-09 12:40 ` Fabiano Rosas
2026-01-19 11:28 ` Prasad Pandit
24 siblings, 1 reply; 58+ messages in thread
From: Fabiano Rosas @ 2026-01-09 12:40 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, berrange, Li Zhijian
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>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/channel.c | 28 ++++++++++++++++++++++++----
migration/exec.c | 8 ++++----
migration/exec.h | 5 ++++-
migration/fd.c | 13 +++++++------
migration/fd.h | 7 +++++--
migration/file.c | 18 ++++++++++--------
migration/file.h | 5 +++--
migration/rdma.c | 11 +++++------
migration/rdma.h | 4 ++--
9 files changed, 64 insertions(+), 35 deletions(-)
diff --git a/migration/channel.c b/migration/channel.c
index cee78532ea..589a5520fe 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -37,26 +37,40 @@
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)
diff --git a/migration/exec.c b/migration/exec.c
index c3085e803e..a1a7ede3b4 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -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,
diff --git a/migration/exec.h b/migration/exec.h
index e7e8e475ac..3e39270dce 100644
--- a/migration/exec.h
+++ b/migration/exec.h
@@ -20,10 +20,13 @@
#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
diff --git a/migration/fd.c b/migration/fd.c
index b689426ad4..bbf380d1a0 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -49,12 +49,13 @@ 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)) {
@@ -66,12 +67,12 @@ void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)
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,
diff --git a/migration/fd.h b/migration/fd.h
index 7211629270..ce0b751273 100644
--- a/migration/fd.h
+++ b/migration/fd.h
@@ -16,8 +16,11 @@
#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
diff --git a/migration/file.c b/migration/file.c
index b7b0fb5194..5618aced49 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -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,
diff --git a/migration/file.h b/migration/file.h
index 9b1e874bb7..5936c64fea 100644
--- a/migration/file.h
+++ b/migration/file.h
@@ -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);
diff --git a/migration/rdma.c b/migration/rdma.c
index b726392097..5d78c1827a 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3934,8 +3934,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;
@@ -3945,7 +3945,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);
@@ -3995,12 +3995,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;
}
diff --git a/migration/rdma.h b/migration/rdma.h
index 170c25cf44..8a6515f130 100644
--- a/migration/rdma.h
+++ b/migration/rdma.h
@@ -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);
--
2.51.0
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH v3 25/25] migration/channel: Centralize calling migration_channel_connect_outgoing
2026-01-09 12:40 ` [PATCH v3 25/25] migration/channel: Centralize calling migration_channel_connect_outgoing Fabiano Rosas
@ 2026-01-19 11:28 ` Prasad Pandit
0 siblings, 0 replies; 58+ messages in thread
From: Prasad Pandit @ 2026-01-19 11:28 UTC (permalink / raw)
To: Fabiano Rosas; +Cc: qemu-devel, peterx, berrange, Li Zhijian
On Fri, 9 Jan 2026 at 18:12, Fabiano Rosas <farosas@suse.de> wrote:
> 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>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> migration/channel.c | 28 ++++++++++++++++++++++++----
> migration/exec.c | 8 ++++----
> migration/exec.h | 5 ++++-
> migration/fd.c | 13 +++++++------
> migration/fd.h | 7 +++++--
> migration/file.c | 18 ++++++++++--------
> migration/file.h | 5 +++--
> migration/rdma.c | 11 +++++------
> migration/rdma.h | 4 ++--
> 9 files changed, 64 insertions(+), 35 deletions(-)
>
> diff --git a/migration/channel.c b/migration/channel.c
> index cee78532ea..589a5520fe 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -37,26 +37,40 @@
> 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)
> diff --git a/migration/exec.c b/migration/exec.c
> index c3085e803e..a1a7ede3b4 100644
> --- a/migration/exec.c
> +++ b/migration/exec.c
> @@ -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,
> diff --git a/migration/exec.h b/migration/exec.h
> index e7e8e475ac..3e39270dce 100644
> --- a/migration/exec.h
> +++ b/migration/exec.h
> @@ -20,10 +20,13 @@
> #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
> diff --git a/migration/fd.c b/migration/fd.c
> index b689426ad4..bbf380d1a0 100644
> --- a/migration/fd.c
> +++ b/migration/fd.c
> @@ -49,12 +49,13 @@ 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)) {
> @@ -66,12 +67,12 @@ void fd_connect_outgoing(MigrationState *s, const char *fdname, Error **errp)
> 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,
> diff --git a/migration/fd.h b/migration/fd.h
> index 7211629270..ce0b751273 100644
> --- a/migration/fd.h
> +++ b/migration/fd.h
> @@ -16,8 +16,11 @@
>
> #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
> diff --git a/migration/file.c b/migration/file.c
> index b7b0fb5194..5618aced49 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -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,
> diff --git a/migration/file.h b/migration/file.h
> index 9b1e874bb7..5936c64fea 100644
> --- a/migration/file.h
> +++ b/migration/file.h
> @@ -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);
> diff --git a/migration/rdma.c b/migration/rdma.c
> index b726392097..5d78c1827a 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -3934,8 +3934,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;
> @@ -3945,7 +3945,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);
> @@ -3995,12 +3995,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;
> }
> diff --git a/migration/rdma.h b/migration/rdma.h
> index 170c25cf44..8a6515f130 100644
> --- a/migration/rdma.h
> +++ b/migration/rdma.h
> @@ -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);
>
> --
* Change looks okay.
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Thank you.
---
- Prasad
^ permalink raw reply [flat|nested] 58+ messages in thread