old-style vmstate doesn't use vmsd and instead rely on SaveStateEntry
ops. Check is_active for old-style vmstate to determine whether they
should be skipped during migration.

Signed-off-by: Yanfei Xu <[email protected]>
---
 migration/savevm.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 197c89e0e6..7eee83ffca 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1030,15 +1030,27 @@ static int vmstate_save(QEMUFile *f, SaveStateEntry 
*se, JSONWriter *vmdesc,
                         Error **errp)
 {
     int ret;
+    const bool has_old_style = se->ops && se->ops->save_state;
 
-    if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
+    if (!has_old_style && !se->vmsd) {
         return 0;
+    } else if (has_old_style && se->vmsd) {
+        error_report("%s: '%s' (section_id=%u): unexpected: both vmsd (%s) and"
+                     " old-style save_state are set", __func__, se->idstr,
+                     se->section_id, se->vmsd->name);
+        return -EINVAL;
     }
+
     if (se->vmsd && !vmstate_section_needed(se->vmsd, se->opaque)) {
         trace_savevm_section_skip(se->idstr, se->section_id);
         return 0;
     }
 
+    if (has_old_style && se->ops->is_active && 
!se->ops->is_active(se->opaque)) {
+        trace_savevm_section_skip(se->idstr, se->section_id);
+        return 0;
+    }
+
     trace_savevm_section_start(se->idstr, se->section_id);
     save_section_header(f, se, QEMU_VM_SECTION_FULL);
     if (vmdesc) {
-- 
2.20.1

Reply via email to