migration: Add .save_prepare() handler to struct SaveVMHandlers
Add a new .save_prepare() handler to struct SaveVMHandlers. This handler is called early, even before migration starts, and can be used by devices to perform early checks. Refactor migrate_init() to be able to return errors and call .save_prepare() from there. Suggested-by: Peter Xu <peterx@redhat.com> Signed-off-by: Avihai Horon <avihaih@nvidia.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
f543aa222d
commit
08fc4cb517
@ -20,6 +20,11 @@ typedef struct SaveVMHandlers {
|
||||
/* This runs inside the iothread lock. */
|
||||
SaveStateHandler *save_state;
|
||||
|
||||
/*
|
||||
* save_prepare is called early, even before migration starts, and can be
|
||||
* used to perform early checks.
|
||||
*/
|
||||
int (*save_prepare)(void *opaque, Error **errp);
|
||||
void (*save_cleanup)(void *opaque);
|
||||
int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque);
|
||||
int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
|
||||
|
@ -1392,8 +1392,15 @@ bool migration_is_active(MigrationState *s)
|
||||
s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
|
||||
}
|
||||
|
||||
void migrate_init(MigrationState *s)
|
||||
int migrate_init(MigrationState *s, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = qemu_savevm_state_prepare(errp);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reinitialise all migration state, except
|
||||
* parameters/capabilities that the user set, and
|
||||
@ -1432,6 +1439,8 @@ void migrate_init(MigrationState *s)
|
||||
memset(&mig_stats, 0, sizeof(mig_stats));
|
||||
memset(&compression_counters, 0, sizeof(compression_counters));
|
||||
migration_reset_vfio_bytes_transferred();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int migrate_add_blocker_internal(Error *reason, Error **errp)
|
||||
@ -1641,7 +1650,9 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
|
||||
migrate_set_block_incremental(true);
|
||||
}
|
||||
|
||||
migrate_init(s);
|
||||
if (migrate_init(s, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in);
|
||||
bool migration_is_setup_or_active(int state);
|
||||
bool migration_is_running(int state);
|
||||
|
||||
void migrate_init(MigrationState *s);
|
||||
int migrate_init(MigrationState *s, Error **errp);
|
||||
bool migration_is_blocked(Error **errp);
|
||||
/* True if outgoing migration has entered postcopy phase */
|
||||
bool migration_in_postcopy(void);
|
||||
|
@ -1233,6 +1233,30 @@ bool qemu_savevm_state_guest_unplug_pending(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
int qemu_savevm_state_prepare(Error **errp)
|
||||
{
|
||||
SaveStateEntry *se;
|
||||
int ret;
|
||||
|
||||
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
||||
if (!se->ops || !se->ops->save_prepare) {
|
||||
continue;
|
||||
}
|
||||
if (se->ops->is_active) {
|
||||
if (!se->ops->is_active(se->opaque)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ret = se->ops->save_prepare(se->opaque, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qemu_savevm_state_setup(QEMUFile *f)
|
||||
{
|
||||
MigrationState *ms = migrate_get_current();
|
||||
@ -1619,7 +1643,10 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
migrate_init(ms);
|
||||
ret = migrate_init(ms, errp);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
ms->to_dst_file = f;
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
bool qemu_savevm_state_blocked(Error **errp);
|
||||
void qemu_savevm_non_migratable_list(strList **reasons);
|
||||
int qemu_savevm_state_prepare(Error **errp);
|
||||
void qemu_savevm_state_setup(QEMUFile *f);
|
||||
bool qemu_savevm_state_guest_unplug_pending(void);
|
||||
int qemu_savevm_state_resume_prepare(MigrationState *s);
|
||||
|
Loading…
Reference in New Issue
Block a user