[libvirt] [PATCH RFC 33/39] qemu: monitor: Add API to retrieve blockstats by nodenames

Peter Krempa pkrempa at redhat.com
Wed Jul 25 15:58:04 UTC 2018


Add workers that allow collecting the 'blockstats' from qemu by
nodename. This will replace the old usage when using -blockdev as
query-blockstats does not report anything when using the old approach.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_monitor.c      | 25 ++++++++++++++++
 src/qemu/qemu_monitor.h      |  6 ++++
 src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |  4 +++
 4 files changed, 104 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 9d58217376..bc9c7d53b0 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2300,6 +2300,31 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
 }


+int
+qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
+                             virHashTablePtr *ret_stats,
+                             int *nstats)
+{
+    virHashTablePtr hash = NULL;
+    int ret = -1;
+
+    QEMU_CHECK_MONITOR(mon);
+
+    if (!(hash = virHashCreate(10, virHashValueFree)))
+        goto cleanup;
+
+    if (qemuMonitorJSONGetBlockStatsInfo(mon, hash, nstats) < 0)
+        goto cleanup;
+
+    VIR_STEAL_PTR(*ret_stats, hash);
+    ret = 0;
+
+ cleanup:
+    virHashFree(hash);
+    return ret;
+}
+
+
 /* Updates "stats" to fill virtual and physical size of the image */
 int
 qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 3e902e1e8b..8ede11c82c 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -592,6 +592,12 @@ int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
                                     bool backingChain)
     ATTRIBUTE_NONNULL(2);

+int
+qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
+                             virHashTablePtr *ret_stats,
+                             int *nstats)
+    ATTRIBUTE_NONNULL(2);
+
 int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
                                         virHashTablePtr stats,
                                         bool backingChain)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 6d76f4a2d5..02a3f09a8b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2467,6 +2467,75 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
 }


+struct qemuMonitorJSONGetBlockstatsInfoArrayWorkerData {
+    virHashTablePtr hash;
+    int nstats;
+};
+
+
+static int
+qemuMonitorJSONGetBlockStatsInfoArrayWorker(size_t pos ATTRIBUTE_UNUSED,
+                                            virJSONValuePtr val,
+                                            void *opaque)
+{
+    struct qemuMonitorJSONGetBlockstatsInfoArrayWorkerData *data = opaque;
+    qemuBlockStatsPtr bstats = NULL;
+    const char *nodename;
+    int nstats = 0;
+    int ret = -1;
+
+    if (!(nodename = virJSONValueObjectGetString(val, "node-name"))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("missing node name in query-blockstats reply"));
+        return -1;
+    }
+
+    if (!(bstats = qemuMonitorJSONBlockStatsCollectData(val, &nstats)))
+        goto cleanup;
+
+    if (nstats > data->nstats)
+        data->nstats = nstats;
+
+    if (virHashAddEntry(data->hash, nodename, bstats) < 0)
+        goto cleanup;
+    bstats = NULL;
+
+    ret = 1; /* we don't want to steal the value from the JSON array */
+
+ cleanup:
+    VIR_FREE(bstats);
+    return ret;
+}
+
+
+int
+qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
+                                 virHashTablePtr hash,
+                                 int *nstats)
+{
+    struct qemuMonitorJSONGetBlockstatsInfoArrayWorkerData data = { hash, 0 };
+    virJSONValuePtr devices;
+    int ret = -1;
+
+    if (!(devices = qemuMonitorJSONQueryBlockstats(mon, true)))
+        return -1;
+
+    if (virJSONValueArrayForeachSteal(devices,
+                                      qemuMonitorJSONGetBlockStatsInfoArrayWorker,
+                                      &data) < 0)
+        goto cleanup;
+
+    if (nstats)
+        *nstats = data.nstats;
+
+    ret = 0;
+
+ cleanup:
+    virJSONValueFree(devices);
+    return ret;
+}
+
+
 static int
 qemuMonitorJSONBlockStatsUpdateCapacityData(virJSONValuePtr image,
                                             const char *name,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 7cdec6e231..6042f7161f 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -95,6 +95,10 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
 int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
                                             virHashTablePtr stats,
                                             bool backingChain);
+int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
+                                     virHashTablePtr hash,
+                                     int *nstats);
+
 int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,
                                const char *devce,
                                unsigned long long size);
-- 
2.16.2




More information about the libvir-list mailing list