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>
---
migration/savevm.h | 3 +--
migration/colo.c | 2 +-
migration/savevm.c | 30 +++++++++++++++---------------
3 files changed, 17 insertions(+), 18 deletions(-)
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,
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
--
2.50.1