]> Git Repo - qemu.git/commitdiff
migration: Read state once
authorDr. David Alan Gilbert <[email protected]>
Wed, 13 Apr 2022 11:33:29 +0000 (12:33 +0100)
committerDr. David Alan Gilbert <[email protected]>
Thu, 21 Apr 2022 18:36:46 +0000 (19:36 +0100)
The 'status' field for the migration is updated normally using
an atomic operation from the migration thread.
Most readers of it aren't that careful, and in most cases it doesn't
matter.

In query_migrate->fill_source_migration_info the 'state'
is read twice; the first time to decide which state fields to fill in,
and then secondly to copy the state to the status field; that can end up
with a status that's inconsistent; e.g. setting up the fields
for 'setup' and then having an 'active' status.  In that case
libvirt gets upset by the lack of ram info.
The symptom is:
   libvirt.libvirtError: internal error: migration was active, but no RAM info was set

Read the state exactly once in fill_source_migration_info.

This is a possible fix for:
https://bugzilla.redhat.com/show_bug.cgi?id=2074205

Signed-off-by: Dr. David Alan Gilbert <[email protected]>
Message-Id: <20220413113329[email protected]>
Reviewed-by: Juan Quintela <[email protected]>
Reviewed-by: Peter Xu <[email protected]>
Signed-off-by: Dr. David Alan Gilbert <[email protected]>
migration/migration.c

index cc00b344a908c2eb76f4aee08e0c76eaa3e41bc0..5a31b23bd6241702bbf195c7fbc8a7bb4b2daa90 100644 (file)
@@ -1084,6 +1084,7 @@ static void populate_disk_info(MigrationInfo *info)
 static void fill_source_migration_info(MigrationInfo *info)
 {
     MigrationState *s = migrate_get_current();
+    int state = qatomic_read(&s->state);
     GSList *cur_blocker = migration_blockers;
 
     info->blocked_reasons = NULL;
@@ -1103,7 +1104,7 @@ static void fill_source_migration_info(MigrationInfo *info)
     }
     info->has_blocked_reasons = info->blocked_reasons != NULL;
 
-    switch (s->state) {
+    switch (state) {
     case MIGRATION_STATUS_NONE:
         /* no migration has happened ever */
         /* do not overwrite destination migration status */
@@ -1148,7 +1149,7 @@ static void fill_source_migration_info(MigrationInfo *info)
         info->has_status = true;
         break;
     }
-    info->status = s->state;
+    info->status = state;
 }
 
 typedef enum WriteTrackingSupport {
This page took 0.034563 seconds and 4 git commands to generate.