From: Peter Xu <[email protected]> Use qemu_savevm_state_non_iterable*() helpers for saving device states, rather than walking the vmstate handlers on its own.
Non-iterables can be either early_setup devices, or otherwise. Note that QEMU only has one early_setup device currently, which is virtio-mem, and I highly doubt if it is used in either COLO or Xen users.. However this step is still better needed to provide full coverage of all non-iterable vmstates. When at it, allow it to report errors. Cc: David Woodhouse <[email protected]> Cc: Paul Durrant <[email protected]> Signed-off-by: Peter Xu <[email protected]> Reviewed-by: Fabiano Rosas <[email protected]> Tested-by: Lukas Straub <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Signed-off-by: Fabiano Rosas <[email protected]> --- migration/colo.c | 2 +- migration/savevm.c | 30 +++++++++++++++--------------- migration/savevm.h | 3 +-- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/migration/colo.c b/migration/colo.c index db804b25a9..f7a5bd3619 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -454,7 +454,7 @@ static int colo_do_checkpoint_transaction(MigrationState *s, } /* Note: device state is saved into buffer */ - ret = qemu_save_device_state(fb); + ret = qemu_save_device_state(fb, &local_err); bql_unlock(); if (ret < 0) { diff --git a/migration/savevm.c b/migration/savevm.c index b29272db3b..3a16c467b2 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1887,26 +1887,24 @@ static bool qemu_savevm_se_iterable(SaveStateEntry *se) return se->ops && se->ops->save_setup; } -int qemu_save_device_state(QEMUFile *f) +int qemu_save_device_state(QEMUFile *f, Error **errp) { - Error *local_err = NULL; - SaveStateEntry *se; + int ret; - cpu_synchronize_all_states(); + /* Both COLO and Xen never use vmdesc, hence NULL. */ + ret = qemu_savevm_state_non_iterable_early(f, NULL, errp); + if (ret) { + return ret; + } - QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { - int ret; - - ret = vmstate_save(f, se, NULL, &local_err); - if (ret) { - error_report_err(local_err); - return ret; - } + ret = qemu_savevm_state_non_iterable(f, errp); + if (ret) { + return ret; } qemu_savevm_state_end(f); - return qemu_file_get_error(f); + return 0; } static SaveStateEntry *find_se(const char *idstr, uint32_t instance_id) @@ -3346,9 +3344,11 @@ void qmp_xen_save_devices_state(const char *filename, bool has_live, bool live, f = qemu_file_new_output(QIO_CHANNEL(ioc)); object_unref(OBJECT(ioc)); qemu_savevm_send_header(f); - ret = qemu_save_device_state(f); + ret = qemu_save_device_state(f, errp); if (ret < 0 || qemu_fclose(f) < 0) { - error_setg(errp, "saving Xen device state failed"); + if (*errp == NULL) { + error_setg(errp, "saving Xen device state failed"); + } } else { /* libxl calls the QMP command "stop" before calling * "xen-save-devices-state" and in case of migration failure, libxl diff --git a/migration/savevm.h b/migration/savevm.h index 6a589b2990..2ba0881f3b 100644 --- a/migration/savevm.h +++ b/migration/savevm.h @@ -66,8 +66,7 @@ void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name, uint64_t *start_list, uint64_t *length_list); void qemu_savevm_send_colo_enable(QEMUFile *f); -int qemu_save_device_state(QEMUFile *f); - +int qemu_save_device_state(QEMUFile *f, Error **errp); int qemu_loadvm_state(QEMUFile *f, Error **errp); void qemu_loadvm_state_cleanup(MigrationIncomingState *mis); int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis, -- 2.51.0
