[libvirt] [RFC PATCHv2 7/8] threshold: scrape threshold data from QMP

Eric Blake eblake at redhat.com
Fri Jun 12 19:29:31 UTC 2015


Expose threshold information by collecting the information from
QMP commands.  qemu has a way to get threshold information on all
elements of a block chain, but only if libvirt provides node names
for each node, and then correlates 'query-named-block-nodes' back
to the names on each chain element.  So for now, we only worry
about the threshold of the active layer of a chain.

* src/qemu/qemu_monitor.h (_qemuBlockStats): Add member.
* src/qemu/qemu_monitor_json.c
(qemuMonitorJSONBlockStatsUpdateCapacity): Populate it.
* src/qemu/qemu_driver.c (qemuDomainGetStatsOneBlock): Expose it.
* tests/qemumonitortest.c (testBlockInfoData): Deal with new
member.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/qemu/qemu_driver.c       |  6 ++++++
 src/qemu/qemu_monitor.h      |  1 +
 src/qemu/qemu_monitor_json.c | 16 ++++++++++++++++
 tests/qemumonitortest.c      | 13 +++++++------
 4 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6bb8549..74a6680 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19370,6 +19370,12 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
     QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, block_idx,
                             "fl.times", entry->flush_total_times);

+    /* TODO: Until we can set thresholds on backing elements, we only
+     * report the threshold on the active layer.  */
+    if (!backing_idx)
+        QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
+                                 "write-threshold", entry->write_threshold);
+
     QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
                              "allocation", entry->wr_highest_offset);

diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 381c0a6..45afba4 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -384,6 +384,7 @@ struct _qemuBlockStats {
     unsigned long long capacity;
     unsigned long long physical;
     unsigned long long wr_highest_offset;
+    unsigned long long write_threshold;
 };

 int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 8dd1279..2cb3c4b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1942,6 +1942,7 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
         virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
         virJSONValuePtr inserted;
         virJSONValuePtr image;
+        virJSONValuePtr threshold;
         const char *dev_name;

         if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
@@ -1967,6 +1968,21 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
                                                        stats,
                                                        backingChain) < 0)
             goto cleanup;
+
+        /* For the top layer only, additionally populate the
+         * write_threshold stat.  TODO: populating it for other layers
+         * requires naming all nodes, and correlating
+         * query-named-block-nodes back to the data learned here.  */
+        if ((threshold = virJSONValueObjectGet(inserted, "write_threshold"))) {
+            char *entry_name = qemuDomainStorageAlias(dev_name, 0);
+            qemuBlockStatsPtr bstats = virHashLookup(stats, entry_name);
+            VIR_FREE(entry_name);
+
+            if (bstats &&
+                virJSONValueGetNumberUlong(threshold,
+                                           &bstats->write_threshold) < 0)
+                goto cleanup;
+        }
     }

     ret = 0;
diff --git a/tests/qemumonitortest.c b/tests/qemumonitortest.c
index 0125962..6dfb7ad 100644
--- a/tests/qemumonitortest.c
+++ b/tests/qemumonitortest.c
@@ -93,12 +93,13 @@ struct blockInfoData {

 static const struct blockInfoData testBlockInfoData[] =
 {
-/* NAME, rd_req, rd_bytes, wr_req, wr_bytes, rd_total_time, wr_total_time, flush_req, flush_total_time */
-    {"vda", {11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0}},
-    {"vdb", {21, 22, 23, 24, 25, 26, 27, 28, 0, 0, 0}},
-    {"vdc", {31, 32, 33, -1, 35, 36, 37, 38, 0, 0, 0}},
-    {"vdd", {-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0}},
-    {"vde", {41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0}}
+    /* NAME, rd_req, rd_bytes, wr_req, wr_bytes, rd_total_time, wr_total_time,
+       flush_req, flush_total_time, write_threshold */
+    {"vda", {11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0}},
+    {"vdb", {21, 22, 23, 24, 25, 26, 27, 28, 0, 0, 0, 0}},
+    {"vdc", {31, 32, 33, -1, 35, 36, 37, 38, 0, 0, 0, 0}},
+    {"vdd", {-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0}},
+    {"vde", {41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0}}
 };

 static const char testBlockInfoReply[] =
-- 
2.4.2




More information about the libvir-list mailing list