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 failure is published, i.e. before the source is told about it over the return path and resumes, or the management sees the MIGRATION event on the target and resumes the source, or the target exits.
Add a migration event for that, sent to the migration notifiers from the failure path of process_incoming_migration_co() before the failure is published. Signed-off-by: Andrey Drobyshev <[email protected]> --- include/migration/misc.h | 5 +++++ migration/migration.c | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/migration/misc.h b/include/migration/misc.h index 019717f4cda..86cc7eefd66 100644 --- a/include/migration/misc.h +++ b/include/migration/misc.h @@ -65,12 +65,17 @@ bool migration_thread_is_self(void); * - MIG_EVENT_SETUP [-> MIG_EVENT_POSTCOPY_START] -> MIG_EVENT_DONE * - MIG_EVENT_SETUP [-> MIG_EVENT_POSTCOPY_START] -> MIG_EVENT_FAILED * - MIG_EVENT_FAILED + * + * MIG_EVENT_INCOMING_FAILED is currently the only event sent on the + * incoming side, when the incoming migration fails and before the failure + * is published. */ typedef enum MigrationEventType { MIG_EVENT_SETUP, MIG_EVENT_POSTCOPY_START, MIG_EVENT_DONE, MIG_EVENT_FAILED, + MIG_EVENT_INCOMING_FAILED, MIG_EVENT_MAX } MigrationEventType; diff --git a/migration/migration.c b/migration/migration.c index fab7949fe11..82a8a252289 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -815,6 +815,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(). + */ + migration_call_notifiers(MIG_EVENT_INCOMING_FAILED, NULL); migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_FAILED); migrate_error_propagate(s, local_err); -- 2.47.1
