On Tue, Oct 06, 2026 at 04:58:39PM +0300, Andrey Drobyshev wrote:
> A device may take over a resource from the source in post_load(), e.g.
> vhost-vsock acquires the device ownership on a CPR target. If the
> incoming migration fails afterwards, there's currently no way for the
> device to give that resource back before the source is told about the
> failure, over the return path or via the MIGRATION event, and resumes,
> or before the target exits.
>
> Add a notifier list for that, called from the failure path of
> process_incoming_migration_co() before the failure is published.
>
> Signed-off-by: Andrey Drobyshev <[email protected]>
Should we better reuse migration_state_notifiers[] and introduce
MIG_EVENT_INCOMING_FAILED?
> ---
> include/migration/misc.h | 7 +++++++
> migration/migration.c | 22 ++++++++++++++++++++++
> 2 files changed, 29 insertions(+)
>
> diff --git a/include/migration/misc.h b/include/migration/misc.h
> index 019717f4cda..08d110750fc 100644
> --- a/include/migration/misc.h
> +++ b/include/migration/misc.h
> @@ -112,6 +112,13 @@ void migration_add_notifier_modes(NotifierWithReturn
> *notify,
> */
> void migration_remove_notifier(NotifierWithReturn *notify);
>
> +/*
> + * Incoming side: @notify is called when an incoming migration fails,
> + * before the target dies or before the source is told about the failure.
> + */
> +void migration_incoming_add_failure_notifier(Notifier *notify);
> +void migration_incoming_remove_failure_notifier(Notifier *notify);
> +
> void migration_file_set_error(int ret, Error *err);
>
> /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
> diff --git a/migration/migration.c b/migration/migration.c
> index fab7949fe11..01e11f91fd9 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -71,6 +71,8 @@
> #define INMIGRATE_DEFAULT_EXIT_ON_ERROR true
>
> static GSList *migration_state_notifiers[MIG_MODE__MAX];
> +static NotifierList incoming_failure_notifiers =
> + NOTIFIER_LIST_INITIALIZER(incoming_failure_notifiers);
>
> /* Messages sent on the return path from destination to source */
> enum mig_rp_message_type {
> @@ -815,6 +817,16 @@ process_incoming_migration_co(void *opaque)
> goto out;
>
> fail:
> + /*
> + * Allow the devices which have registered their callbacks for
> + * migration target failure to undo the changes they may have
> + * done in post_load().
> + *
> + * Do that before the failure is published in any way: the MIGRATION
> + * event emitted by migrate_set_state() below, the return path (if
> + * present) in migration_incoming_state_destroy(), or the exit().
> + */
> + notifier_list_notify(&incoming_failure_notifiers, NULL);
> migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
> MIGRATION_STATUS_FAILED);
> migrate_error_propagate(s, local_err);
> @@ -1590,6 +1602,16 @@ void migration_add_notifier(NotifierWithReturn *notify,
> migration_add_notifier_mode(notify, func, MIG_MODE_NORMAL);
> }
>
> +void migration_incoming_add_failure_notifier(Notifier *notify)
> +{
> + notifier_list_add(&incoming_failure_notifiers, notify);
> +}
> +
> +void migration_incoming_remove_failure_notifier(Notifier *notify)
> +{
> + notifier_remove(notify);
> +}
> +
> void migration_remove_notifier(NotifierWithReturn *notify)
> {
> if (notify->notify) {
>
> --
> 2.47.1
>
--
Peter Xu