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 <dwmw2@infradead.org>
Cc: Paul Durrant <paul@xen.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Tested-by: Lukas Straub <lukasstraub2@web.de>
Link: https://lore.kernel.org/qemu-devel/20260127185254.3954634-25-peterx@redhat.com
Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
Peter Xu
2026-01-27 13:52:54 -05:00
committed by Fabiano Rosas
parent 1580d7346b
commit 32ed27e5b9
3 changed files with 17 additions and 18 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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,