]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_driver: add check for qemu capabilities requirements
authorHiroki Narukawa <hnarukaw@yahoo-corp.jp>
Fri, 15 Oct 2021 09:49:19 +0000 (18:49 +0900)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 18 Oct 2021 08:37:19 +0000 (10:37 +0200)
query-dirty-rate command is used for virsh domstats by default, but this
is available only on qemu >=5.2.0.

By this commit, qemu domain stats will check capabilities requirements before issuing actual query.

Signed-off-by: Hiroki Narukawa <hnarukaw@yahoo-corp.jp>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_driver.c

index 1faab31745747f56826852b472f8d11b34d8a82a..9bcba4b9a45f8222c171cd73b09c83999035bbdb 100644 (file)
@@ -18710,13 +18710,30 @@ static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
 
 static int
 qemuDomainGetStatsCheckSupport(unsigned int *stats,
-                               bool enforce)
+                               bool enforce,
+                               virDomainObj *vm)
 {
+    qemuDomainObjPrivate *priv = vm->privateData;
     unsigned int supportedstats = 0;
     size_t i;
 
-    for (i = 0; qemuDomainGetStatsWorkers[i].func; i++)
-        supportedstats |= qemuDomainGetStatsWorkers[i].stats;
+    for (i = 0; qemuDomainGetStatsWorkers[i].func; i++) {
+        bool supportedByQemu = true;
+        virQEMUCapsFlags *requiredCaps = qemuDomainGetStatsWorkers[i].requiredCaps;
+
+        while (requiredCaps && *requiredCaps != QEMU_CAPS_LAST) {
+            if (!virQEMUCapsGet(priv->qemuCaps, *requiredCaps)) {
+                supportedByQemu = false;
+                break;
+            }
+
+            requiredCaps++;
+        }
+
+        if (supportedByQemu) {
+            supportedstats |= qemuDomainGetStatsWorkers[i].stats;
+        }
+    }
 
     if (*stats == 0) {
         *stats = supportedstats;
@@ -18726,7 +18743,7 @@ qemuDomainGetStatsCheckSupport(unsigned int *stats,
     if (enforce &&
         *stats & ~supportedstats) {
         virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
-                       _("Stats types bits 0x%x are not supported by this daemon"),
+                       _("Stats types bits 0x%x are not supported by this daemon or QEMU"),
                        *stats & ~supportedstats);
         return -1;
     }
@@ -18801,7 +18818,6 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
     int nstats = 0;
     size_t i;
     int ret = -1;
-    unsigned int privflags = 0;
     unsigned int domflags = 0;
     unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
                                    VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
@@ -18817,9 +18833,6 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
     if (virConnectGetAllDomainStatsEnsureACL(conn) < 0)
         return -1;
 
-    if (qemuDomainGetStatsCheckSupport(&stats, enforce) < 0)
-        return -1;
-
     if (ndoms) {
         if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms,
                                     &nvms, virConnectGetAllDomainStatsCheckACL,
@@ -18834,16 +18847,24 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
 
     tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1);
 
-    if (qemuDomainGetStatsNeedMonitor(stats))
-        privflags |= QEMU_DOMAIN_STATS_HAVE_JOB;
-
     for (i = 0; i < nvms; i++) {
         virDomainStatsRecordPtr tmp = NULL;
+        unsigned int privflags = 0;
+        unsigned int requestedStats = stats;
+
         domflags = 0;
         vm = vms[i];
 
         virObjectLock(vm);
 
+        if (qemuDomainGetStatsCheckSupport(&requestedStats, enforce, vm) < 0) {
+            virObjectUnlock(vm);
+            goto cleanup;
+        }
+
+        if (qemuDomainGetStatsNeedMonitor(requestedStats))
+            privflags |= QEMU_DOMAIN_STATS_HAVE_JOB;
+
         if (HAVE_JOB(privflags)) {
             int rv;
 
@@ -18859,7 +18880,7 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
 
         if (flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING)
             domflags |= QEMU_DOMAIN_STATS_BACKING;
-        if (qemuDomainGetStats(conn, vm, stats, &tmp, domflags) < 0) {
+        if (qemuDomainGetStats(conn, vm, requestedStats, &tmp, domflags) < 0) {
             if (HAVE_JOB(domflags) && vm)
                 qemuDomainObjEndJob(driver, vm);