]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Store supported migration capabilities in a bitmap
authorJiri Denemark <jdenemar@redhat.com>
Tue, 17 Oct 2017 19:39:41 +0000 (21:39 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 20 Oct 2017 11:36:56 +0000 (13:36 +0200)
Each time we need to check whether a given migration capability is
supported by QEMU, we call query-migrate-capabilities QMP command and
lookup the capability in the returned list. Asking for the list of
supported capabilities once when we connect to QEMU and storing the
result in a bitmap is much better and we don't need to enter a monitor
just to check whether a migration capability is supported.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_process.c

index 00610edf10497f8d245240143ac0cca50dc4d850..e34b8be28451cb97bed6c3d4f23bc8665fbf7c73 100644 (file)
@@ -1806,6 +1806,9 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
 
     priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT;
     priv->allowReboot = VIR_TRISTATE_BOOL_ABSENT;
+
+    virBitmapFree(priv->migrationCaps);
+    priv->migrationCaps = NULL;
 }
 
 
@@ -10242,3 +10245,68 @@ qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def,
     }
     return true;
 }
+
+
+int
+qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
+                                     virDomainObjPtr vm,
+                                     qemuDomainAsyncJob asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    char **caps = NULL;
+    char **capStr;
+    int ret = -1;
+    int rc;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    rc = qemuMonitorGetMigrationCapabilities(priv->mon, &caps);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        goto cleanup;
+
+    if (!caps) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    priv->migrationCaps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST);
+    if (!priv->migrationCaps)
+        goto cleanup;
+
+    for (capStr = caps; *capStr; capStr++) {
+        int cap = qemuMonitorMigrationCapsTypeFromString(*capStr);
+
+        if (cap < 0) {
+            VIR_DEBUG("Unknown migration capability: '%s'", *capStr);
+        } else {
+            ignore_value(virBitmapSetBit(priv->migrationCaps, cap));
+            VIR_DEBUG("Found migration capability: '%s'", *capStr);
+        }
+    }
+
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) {
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+            goto cleanup;
+
+        rc = qemuMonitorSetMigrationCapability(priv->mon,
+                                               QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
+                                               true);
+
+        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            goto cleanup;
+
+        if (rc < 0) {
+            virResetLastError();
+            VIR_DEBUG("Cannot enable migration events; clearing capability");
+            virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
+        }
+    }
+
+    ret = 0;
+
+ cleanup:
+    virStringListFree(caps);
+    return ret;
+}
index 39cb68b3c25df4e457ddaa2dc1682d8255d621b0..3b4272047a8c186bb3b2b9499f582d6fc316c8c9 100644 (file)
@@ -324,6 +324,10 @@ struct _qemuDomainObjPrivate {
 
     /* Tracks blockjob state for vm. Valid only while reconnecting to qemu. */
     virTristateBool reconnectBlockjobs;
+
+    /* Migration capabilities. Rechecked on reconnect, not to be saved in
+     * private XML. */
+    virBitmapPtr migrationCaps;
 };
 
 # define QEMU_DOMAIN_PRIVATE(vm)        \
@@ -1000,4 +1004,9 @@ bool qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def,
                                     virQEMUCapsPtr qemuCaps,
                                     const char *devicename);
 
+int
+qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
+                                     virDomainObjPtr vm,
+                                     qemuDomainAsyncJob asyncJob);
+
 #endif /* __QEMU_DOMAIN_H__ */
index 8d551d071564a3a118ddba885fcfd1993052b184..fdc868912c1ba34295d90c226bd5a536908e5088 100644 (file)
@@ -1816,18 +1816,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
     if (qemuProcessInitMonitor(driver, vm, asyncJob) < 0)
         return -1;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
-        return -1;
-
-    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT) &&
-        qemuMonitorSetMigrationCapability(priv->mon,
-                                          QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
-                                          true) < 0) {
-        VIR_DEBUG("Cannot enable migration events; clearing capability");
-        virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
-    }
-
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainCheckMigrationCapabilities(driver, vm, asyncJob) < 0)
         return -1;
 
     return 0;