[RFC PATCH 5/6] qemu_driver: add the vCPU stats by KVM to the current stats

Amneesh Singh natto at weirdnatto.in
Wed Sep 7 10:34:22 UTC 2022


This patch adds the stats queried by qemuMonitorQueryStats for vCPU and
add them according to their QOM device path

Signed-off-by: Amneesh Singh <natto at weirdnatto.in>
---
 src/qemu/qemu_driver.c | 86 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ea7d74806c..79146b6bb8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17966,6 +17966,68 @@ qemuDomainGetStatsBalloon(virQEMUDriver *driver G_GNUC_UNUSED,
 }
 
 
+static void
+qemuDomainAddStatsFromHashTable(GHashTable *stats,
+                                GHashTable *schema,
+                                const char *prefix,
+                                virTypedParamList *params)
+{
+    GHashTableIter iter;
+    virJSONValue *value;
+    char *key;
+
+    if (!stats || !schema)
+        return;
+
+    g_hash_table_iter_init(&iter, stats);
+
+    while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&value)) {
+        qemuMonitorQueryStatsSchemaData *data = g_hash_table_lookup(schema, key);
+        const char *type = NULL;
+
+        if (!data)
+            continue;
+
+        switch (data->type) {
+        case QEMU_MONITOR_QUERY_STATS_TYPE_CUMULATIVE:
+            type = "sum";
+            break;
+        case QEMU_MONITOR_QUERY_STATS_TYPE_INSTANT:
+            type = "cur";
+            break;
+
+        case QEMU_MONITOR_QUERY_STATS_TYPE_PEAK:
+            type = "max";
+            break;
+
+        case QEMU_MONITOR_QUERY_STATS_TYPE_LOG2_HISTOGRAM:
+        case QEMU_MONITOR_QUERY_STATS_TYPE_LINEAR_HISTOGRAM:
+        case QEMU_MONITOR_QUERY_STATS_TYPE_LAST:
+        default:
+            continue;
+        }
+
+        if (data->unit == QEMU_MONITOR_QUERY_STATS_UNIT_BOOLEAN) {
+            bool stat;
+
+            if (virJSONValueGetBoolean(value, &stat) < 0)
+                continue;
+
+            ignore_value(virTypedParamListAddBoolean(params, stat, "%s.%s.%s",
+                                                     prefix, key, type));
+        } else {
+            unsigned long long stat;
+
+            if (virJSONValueGetNumberUlong(value, &stat) < 0)
+                continue;
+
+            ignore_value(virTypedParamListAddULLong(params, stat, "%s.%s.%s",
+                                                    prefix, key, type));
+        }
+    }
+}
+
+
 static int
 qemuDomainGetStatsVcpu(virQEMUDriver *driver G_GNUC_UNUSED,
                        virDomainObj *dom,
@@ -17979,6 +18041,8 @@ qemuDomainGetStatsVcpu(virQEMUDriver *driver G_GNUC_UNUSED,
     virVcpuInfoPtr cpuinfo = NULL;
     g_autofree unsigned long long *cpuwait = NULL;
     g_autofree unsigned long long *cpudelay = NULL;
+    qemuDomainObjPrivate *priv = dom->privateData;
+    g_autoptr(virJSONValue) queried_stats = NULL;
 
     if (virTypedParamListAddUInt(params, virDomainDefGetVcpus(dom->def),
                                  "vcpu.current") < 0)
@@ -18007,7 +18071,21 @@ qemuDomainGetStatsVcpu(virQEMUDriver *driver G_GNUC_UNUSED,
         goto cleanup;
     }
 
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_STATS) &&
+        !qemuDomainRefreshStatsSchema(dom) &&
+        HAVE_JOB(privflags)) {
+        qemuDomainObjEnterMonitor(dom);
+        queried_stats = qemuMonitorQueryStats(priv->mon,
+                                              QEMU_MONITOR_QUERY_STATS_TARGET_VCPU,
+                                              NULL, NULL);
+        qemuDomainObjExitMonitor(dom);
+    }
+
     for (i = 0; i < virDomainDefGetVcpus(dom->def); i++) {
+        virJSONValue *stat_obj = NULL;
+        g_autoptr(GHashTable) stats = NULL;
+        g_autofree char *prefix = g_strdup_printf("vcpu.%u", cpuinfo[i].number);
+
         if (virTypedParamListAddInt(params, cpuinfo[i].state,
                                     "vcpu.%u.state", cpuinfo[i].number) < 0)
             goto cleanup;
@@ -18041,6 +18119,14 @@ qemuDomainGetStatsVcpu(virQEMUDriver *driver G_GNUC_UNUSED,
                                             cpuinfo[i].number) < 0)
                 goto cleanup;
         }
+
+        if (!queried_stats)
+            continue;
+
+        stat_obj = qemuMonitorGetStatsByQOMPath(queried_stats, vcpupriv->qomPath);
+        stats = qemuMonitorExtractQueryStats(stat_obj);
+
+        qemuDomainAddStatsFromHashTable(stats, priv->statsSchema, prefix, params);
     }
 
     ret = 0;
-- 
2.37.1



More information about the libvir-list mailing list