This is an incremental step in converting vmstate loading code to report via Error objects instead of printing directly to the console/monitor.
In doing this the callers now actually honour the failures that can be reported instead of carrying on as if everything was normal. Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> --- migration/migration.c | 9 ++++++++- migration/savevm.c | 18 ++++++++++++------ migration/savevm.h | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index a85d101ad8..e814d47796 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -3522,6 +3522,7 @@ static void *migration_thread(void *opaque) int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST); MigThrError thr_error; bool urgent = false; + Error *local_err = NULL; rcu_register_thread(); @@ -3556,7 +3557,12 @@ static void *migration_thread(void *opaque) qemu_savevm_send_colo_enable(s->to_dst_file); } - qemu_savevm_state_setup(s->to_dst_file); + if (qemu_savevm_state_setup(s->to_dst_file, &local_err) < 0) { + error_report_err(local_err); + migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, + MIGRATION_STATUS_FAILED); + goto out; + } if (qemu_savevm_state_guest_unplug_pending()) { migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, @@ -3609,6 +3615,7 @@ static void *migration_thread(void *opaque) trace_migration_thread_after_loop(); migration_iteration_finish(s); + out: object_unref(OBJECT(s)); rcu_unregister_thread(); return NULL; diff --git a/migration/savevm.c b/migration/savevm.c index fdf8b6edfb..318ba547bc 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1159,10 +1159,9 @@ bool qemu_savevm_state_guest_unplug_pending(void) return false; } -void qemu_savevm_state_setup(QEMUFile *f) +int qemu_savevm_state_setup(QEMUFile *f, Error **errp) { SaveStateEntry *se; - Error *local_err = NULL; int ret; trace_savevm_state_setup(); @@ -1180,14 +1179,18 @@ void qemu_savevm_state_setup(QEMUFile *f) ret = se->ops->save_setup(f, se->opaque); save_section_footer(f, se); if (ret < 0) { + error_setg_errno(errp, -ret, + "Failed to setup device state handler"); qemu_file_set_error(f, ret); - break; + return -1; } } - if (precopy_notify(PRECOPY_NOTIFY_SETUP, &local_err)) { - error_report_err(local_err); + if (precopy_notify(PRECOPY_NOTIFY_SETUP, errp)) { + return -1; } + + return 0; } int qemu_savevm_state_resume_prepare(MigrationState *s) @@ -1537,8 +1540,11 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp) qemu_mutex_unlock_iothread(); qemu_savevm_state_header(f); - qemu_savevm_state_setup(f); + ret = qemu_savevm_state_setup(f, errp); qemu_mutex_lock_iothread(); + if (ret < 0) { + goto fail; + } while (1) { ret = qemu_savevm_state_iterate(f, false, errp); diff --git a/migration/savevm.h b/migration/savevm.h index e187640806..b7133655f2 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -30,7 +30,7 @@ #define QEMU_VM_SECTION_FOOTER 0x7e bool qemu_savevm_state_blocked(Error **errp); -void qemu_savevm_state_setup(QEMUFile *f); +int qemu_savevm_state_setup(QEMUFile *f, Error **errp); bool qemu_savevm_state_guest_unplug_pending(void); int qemu_savevm_state_resume_prepare(MigrationState *s); void qemu_savevm_state_header(QEMUFile *f); -- 2.29.2