[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 5/5] RFC: migration: check required entries are loaded, once
From: |
marcandre . lureau |
Subject: |
[PATCH 5/5] RFC: migration: check required entries are loaded, once |
Date: |
Tue, 26 Sep 2023 19:59:25 +0400 |
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
migration/savevm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/migration/savevm.c b/migration/savevm.c
index bb3e99194c..6a17bb0f73 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -217,6 +217,7 @@ typedef struct SaveStateEntry {
void *opaque;
CompatEntry *compat;
int is_ram;
+ bool visited;
} SaveStateEntry;
typedef struct SaveState {
@@ -1718,6 +1719,36 @@ int qemu_save_device_state(QEMUFile *f)
return qemu_file_get_error(f);
}
+static void savevm_reset_visited(void)
+{
+ SaveStateEntry *se;
+
+ QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
+ se->visited = false;
+ }
+}
+
+static bool loadvm_check_visited(Error **errp)
+{
+ SaveStateEntry *se;
+
+ QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
+ if (se->ops && se->ops->is_active && !se->ops->is_active(se->opaque)) {
+ continue;
+ }
+ if (se->vmsd && !vmstate_save_needed(se->vmsd, se->opaque)) {
+ continue;
+ }
+ if (!se->visited) {
+ error_setg(errp, "Missing entry '%s' while loading VM", se->idstr);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
static SaveStateEntry *find_se(const char *idstr, uint32_t instance_id)
{
SaveStateEntry *se;
@@ -2520,6 +2551,11 @@ qemu_loadvm_section_start_full(QEMUFile *f,
MigrationIncomingState *mis)
idstr, instance_id);
return -EINVAL;
}
+ if (se->visited) {
+ error_report("error while loading state for instance 0x%"PRIx32" of"
+ " device '%s'", instance_id, idstr);
+ return -EINVAL;
+ }
/* Validate version */
if (version_id > se->version_id) {
@@ -2546,6 +2582,8 @@ qemu_loadvm_section_start_full(QEMUFile *f,
MigrationIncomingState *mis)
return -EINVAL;
}
+ se->visited = true;
+
return 0;
}
@@ -2852,7 +2890,12 @@ int qemu_loadvm_state(QEMUFile *f)
cpu_synchronize_all_pre_loadvm();
+ savevm_reset_visited();
ret = qemu_loadvm_state_main(f, mis);
+ if (!loadvm_check_visited(&local_err)) {
+ error_report_err(local_err);
+ return -EINVAL;
+ }
qemu_event_set(&mis->main_thread_load_event);
trace_qemu_loadvm_state_post_main(ret);
--
2.41.0
- [PATCH 0/5] RFC: migration: check required entries and sections are loaded, marcandre . lureau, 2023/09/26
- [PATCH 1/5] block/fdc: 'phase' is not needed on load, marcandre . lureau, 2023/09/26
- [PATCH 2/5] virtio: make endian_needed() work during loading, marcandre . lureau, 2023/09/26
- [PATCH 3/5] net/slirp: use different IDs for each instance, marcandre . lureau, 2023/09/26
- [PATCH 4/5] RFC: migration: check required subsections are loaded, once, marcandre . lureau, 2023/09/26
- [PATCH 5/5] RFC: migration: check required entries are loaded, once,
marcandre . lureau <=