[libvirt] [PATCH 2/5] qemu: Store supported migration capabilities in a bitmap

Jiri Denemark jdenemar at redhat.com
Wed Oct 18 11:29:23 UTC 2017


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 at redhat.com>
---
 src/qemu/qemu_domain.c  | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h  |  9 +++++++
 src/qemu/qemu_process.c | 13 +---------
 3 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 05e8b96aa4..a8cabc5727 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1767,6 +1767,9 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
     priv->namespaces = NULL;
 
     priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT;
+
+    virBitmapFree(priv->migrationCaps);
+    priv->migrationCaps = NULL;
 }
 
 
@@ -10122,3 +10125,68 @@ qemuDomainGetMachineName(virDomainObjPtr vm)
 
     return ret;
 }
+
+
+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;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 5201c6a0ac..fb20d8ea63 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -323,6 +323,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)	\
@@ -978,4 +982,9 @@ qemuDomainFixupCPUs(virDomainObjPtr vm,
 char *
 qemuDomainGetMachineName(virDomainObjPtr vm);
 
+int
+qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
+                                     virDomainObjPtr vm,
+                                     qemuDomainAsyncJob asyncJob);
+
 #endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 24675498a2..cea2f90ce1 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -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;
-- 
2.14.2




More information about the libvir-list mailing list