From: Peter Xu Date: Tue, 27 Jan 2026 18:52:54 +0000 (-0500) Subject: migration/colo/xen: Use generic helpers in qemu_save_device_state() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32ed27e5b920695c82c5a397d3837a00a5b5b46a;p=thirdparty%2Fqemu.git migration/colo/xen: Use generic helpers in qemu_save_device_state() 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 Cc: Paul Durrant Signed-off-by: Peter Xu Reviewed-by: Fabiano Rosas Tested-by: Lukas Straub Link: https://lore.kernel.org/qemu-devel/20260127185254.3954634-25-peterx@redhat.com Signed-off-by: Fabiano Rosas --- 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; - - cpu_synchronize_all_states(); + int ret; - QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { - int ret; + /* Both COLO and Xen never use vmdesc, hence NULL. */ + ret = qemu_savevm_state_non_iterable_early(f, NULL, errp); + if (ret) { + return 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,