]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Enable migration events only for fresh QEMU process
authorJiri Denemark <jdenemar@redhat.com>
Wed, 11 May 2022 13:32:58 +0000 (15:32 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 12 May 2022 14:25:57 +0000 (16:25 +0200)
Every running QEMU process we are willing to reconnect (i.e., at least
3.1.0) supports migration events and we can assume the capability is
already enabled since last time libvirt daemon connected to its monitor.

Well, it's not guaranteed though. If libvirt 1.2.17 or older was used to
start QEMU 3.1.0 or newer, migration events would not be enabled. And if
the user decides to upgrade libvirt from 1.2.17 to 8.4.0 while the QEMU
process is still running, they would not be able to migrate the domain
because of disabled migration events. I think we do not really need to
worry about this scenario as libvirt 1.2.17 is 7 years old while QEMU
3.1.0 was released only 3.5 years ago. Thus a chance someone would be
running such configuration should be fairly small and a combination with
upgrading 1.2.17 to 8.4.0 (or newer) with running domains should get it
pretty much to zero. The issue would disappear ff the ancient libvirt is
first upgraded to something older than 8.4.0 and then to the current
libvirt.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/qemu_migration_params.c
src/qemu/qemu_migration_params.h
src/qemu/qemu_process.c

index 26754f03f82da81b7c77063190d3cfd595b129b7..95fd773645a35679cbb0c288067e7ad672a1b400 100644 (file)
@@ -1385,10 +1385,10 @@ qemuMigrationParamsParse(xmlXPathContextPtr ctxt,
 int
 qemuMigrationCapsCheck(virQEMUDriver *driver,
                        virDomainObj *vm,
-                       int asyncJob)
+                       int asyncJob,
+                       bool reconnect)
 {
     qemuDomainObjPrivate *priv = vm->privateData;
-    g_autoptr(virBitmap) migEvent = NULL;
     g_autoptr(virJSONValue) json = NULL;
     g_auto(GStrv) caps = NULL;
     char **capStr;
@@ -1419,22 +1419,24 @@ qemuMigrationCapsCheck(virQEMUDriver *driver,
         }
     }
 
-    migEvent = virBitmapNew(QEMU_MIGRATION_CAP_LAST);
+    if (!reconnect) {
+        g_autoptr(virBitmap) migEvent = virBitmapNew(QEMU_MIGRATION_CAP_LAST);
 
-    ignore_value(virBitmapSetBit(migEvent, QEMU_MIGRATION_CAP_EVENTS));
+        ignore_value(virBitmapSetBit(migEvent, QEMU_MIGRATION_CAP_EVENTS));
 
-    if (!(json = qemuMigrationCapsToJSON(migEvent, migEvent)))
-        return -1;
+        if (!(json = qemuMigrationCapsToJSON(migEvent, migEvent)))
+            return -1;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
-        return -1;
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+            return -1;
 
-    rc = qemuMonitorSetMigrationCapabilities(priv->mon, &json);
+        rc = qemuMonitorSetMigrationCapabilities(priv->mon, &json);
 
-    qemuDomainObjExitMonitor(vm);
+        qemuDomainObjExitMonitor(vm);
 
-    if (rc < 0)
-        return -1;
+        if (rc < 0)
+            return -1;
+    }
 
     /* Migration events capability must always be enabled, clearing it from
      * migration capabilities bitmap makes sure it won't be touched anywhere
index 4a8815e776f80ac0e815e5cfacf742db8e136488..a0909b9f3dc09ef075eee4bcb812580f22f5b770 100644 (file)
@@ -162,7 +162,8 @@ qemuMigrationParamsParse(xmlXPathContextPtr ctxt,
 int
 qemuMigrationCapsCheck(virQEMUDriver *driver,
                        virDomainObj *vm,
-                       int asyncJob);
+                       int asyncJob,
+                       bool reconnect);
 
 bool
 qemuMigrationCapsGet(virDomainObj *vm,
index 2b162989420f122814c3213280f30fb4431aa229..fd4db43a42741f06c654c5014bcb121ef5cbb33a 100644 (file)
@@ -1914,8 +1914,12 @@ qemuProcessInitMonitor(virQEMUDriver *driver,
 
 
 static int
-qemuConnectMonitor(virQEMUDriver *driver, virDomainObj *vm, int asyncJob,
-                   bool retry, qemuDomainLogContext *logCtxt)
+qemuConnectMonitor(virQEMUDriver *driver,
+                   virDomainObj *vm,
+                   int asyncJob,
+                   bool retry,
+                   qemuDomainLogContext *logCtxt,
+                   bool reconnect)
 {
     qemuDomainObjPrivate *priv = vm->privateData;
     qemuMonitor *mon = NULL;
@@ -1968,7 +1972,7 @@ qemuConnectMonitor(virQEMUDriver *driver, virDomainObj *vm, int asyncJob,
     if (qemuProcessInitMonitor(driver, vm, asyncJob) < 0)
         return -1;
 
-    if (qemuMigrationCapsCheck(driver, vm, asyncJob) < 0)
+    if (qemuMigrationCapsCheck(driver, vm, asyncJob, reconnect) < 0)
         return -1;
 
     return 0;
@@ -2353,7 +2357,7 @@ qemuProcessWaitForMonitor(virQEMUDriver *driver,
     VIR_DEBUG("Connect monitor to vm=%p name='%s' retry=%d",
               vm, vm->def->name, retry);
 
-    if (qemuConnectMonitor(driver, vm, asyncJob, retry, logCtxt) < 0)
+    if (qemuConnectMonitor(driver, vm, asyncJob, retry, logCtxt, false) < 0)
         goto cleanup;
 
     /* Try to get the pty path mappings again via the monitor. This is much more
@@ -8773,7 +8777,7 @@ qemuProcessReconnect(void *opaque)
     tryMonReconn = true;
 
     /* XXX check PID liveliness & EXE path */
-    if (qemuConnectMonitor(driver, obj, VIR_ASYNC_JOB_NONE, retry, NULL) < 0)
+    if (qemuConnectMonitor(driver, obj, VIR_ASYNC_JOB_NONE, retry, NULL, true) < 0)
         goto error;
 
     priv->machineName = qemuDomainGetMachineName(obj);