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


Reply via email to