9119d9
From 7245a00d5adcdd74eb8a5051de2a1d52a4107ae8 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <7245a00d5adcdd74eb8a5051de2a1d52a4107ae8@dist-git>
9119d9
From: Eric Blake <eblake@redhat.com>
9119d9
Date: Wed, 17 Dec 2014 03:09:05 -0700
9119d9
Subject: [PATCH] getstats: perform recursion in monitor collection
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1041569
9119d9
9119d9
When requested in a later patch, the QMP command results are now
9119d9
examined recursively.  As qemu_driver will eventually have to
9119d9
read items out of the hash table as stored by this patch, the
9119d9
computation of backing alias string is done in a shared location.
9119d9
9119d9
* src/qemu/qemu_domain.h (qemuDomainStorageAlias): New prototype.
9119d9
* src/qemu/qemu_domain.c (qemuDomainStorageAlias): Implement it.
9119d9
* src/qemu/qemu_monitor_json.c
9119d9
(qemuMonitorJSONGetOneBlockStatsInfo)
9119d9
(qemuMonitorJSONBlockStatsUpdateCapacityOne): Perform recursion.
9119d9
(qemuMonitorJSONGetAllBlockStatsInfo)
9119d9
(qemuMonitorJSONBlockStatsUpdateCapacity): Update callers.
9119d9
9119d9
Signed-off-by: Eric Blake <eblake@redhat.com>
9119d9
(cherry picked from commit b1802714dab51bd5f0214a4d93a2c0b635bc5f14)
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_domain.c       | 16 +++++++++++++++
9119d9
 src/qemu/qemu_domain.h       |  1 +
9119d9
 src/qemu/qemu_monitor_json.c | 48 ++++++++++++++++++++++++++++++++------------
9119d9
 3 files changed, 52 insertions(+), 13 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
9119d9
index 01fa3ac..58fcd75 100644
9119d9
--- a/src/qemu/qemu_domain.c
9119d9
+++ b/src/qemu/qemu_domain.c
9119d9
@@ -2707,6 +2707,22 @@ qemuDomainStorageFileInit(virQEMUDriverPtr driver,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+char *
9119d9
+qemuDomainStorageAlias(const char *device, int depth)
9119d9
+{
9119d9
+    char *alias;
9119d9
+
9119d9
+    if (STRPREFIX(device, QEMU_DRIVE_HOST_PREFIX))
9119d9
+        device += strlen(QEMU_DRIVE_HOST_PREFIX);
9119d9
+
9119d9
+    if (!depth)
9119d9
+        ignore_value(VIR_STRDUP(alias, device));
9119d9
+    else
9119d9
+        ignore_value(virAsprintf(&alias, "%s.%d", device, depth));
9119d9
+    return alias;
9119d9
+}
9119d9
+
9119d9
+
9119d9
 int
9119d9
 qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
9119d9
                              virDomainObjPtr vm,
9119d9
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
9119d9
index ebb282a..9c94a65 100644
9119d9
--- a/src/qemu/qemu_domain.h
9119d9
+++ b/src/qemu/qemu_domain.h
9119d9
@@ -376,6 +376,7 @@ int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
9119d9
 int qemuDomainStorageFileInit(virQEMUDriverPtr driver,
9119d9
                               virDomainObjPtr vm,
9119d9
                               virStorageSourcePtr src);
9119d9
+char *qemuDomainStorageAlias(const char *device, int depth);
9119d9
 
9119d9
 int qemuDomainCleanupAdd(virDomainObjPtr vm,
9119d9
                          qemuDomainCleanupCallback cb);
9119d9
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
9119d9
index 7088409..97151dc 100644
9119d9
--- a/src/qemu/qemu_monitor_json.c
9119d9
+++ b/src/qemu/qemu_monitor_json.c
9119d9
@@ -1839,13 +1839,18 @@ qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
9119d9
 static int
9119d9
 qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
9119d9
                                     const char *dev_name,
9119d9
+                                    int depth,
9119d9
                                     virHashTablePtr hash,
9119d9
-                                    bool backingChain ATTRIBUTE_UNUSED)
9119d9
+                                    bool backingChain)
9119d9
 {
9119d9
     qemuBlockStatsPtr bstats = NULL;
9119d9
     virJSONValuePtr stats;
9119d9
     int ret = -1;
9119d9
+    char *entry_name = qemuDomainStorageAlias(dev_name, depth);
9119d9
+    virJSONValuePtr backing;
9119d9
 
9119d9
+    if (!entry_name)
9119d9
+        goto cleanup;
9119d9
     if (VIR_ALLOC(bstats) < 0)
9119d9
         goto cleanup;
9119d9
 
9119d9
@@ -1921,12 +1926,20 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
9119d9
     /* it's ok to not have this information here. Just skip silently. */
9119d9
     qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
9119d9
 
9119d9
-    if (virHashAddEntry(hash, dev_name, bstats) < 0)
9119d9
+    if (virHashAddEntry(hash, entry_name, bstats) < 0)
9119d9
         goto cleanup;
9119d9
     bstats = NULL;
9119d9
+
9119d9
+    if (backingChain &&
9119d9
+        (backing = virJSONValueObjectGet(dev, "backing")) &&
9119d9
+        qemuMonitorJSONGetOneBlockStatsInfo(backing, dev_name, depth + 1,
9119d9
+                                            hash, true) < 0)
9119d9
+        goto cleanup;
9119d9
+
9119d9
     ret = 0;
9119d9
  cleanup:
9119d9
     VIR_FREE(bstats);
9119d9
+    VIR_FREE(entry_name);
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
@@ -1981,10 +1994,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
9119d9
             goto cleanup;
9119d9
         }
9119d9
 
9119d9
-        if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
9119d9
-            dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
9119d9
-
9119d9
-        if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, hash,
9119d9
+        if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
9119d9
                                                 backingChain) < 0)
9119d9
             goto cleanup;
9119d9
 
9119d9
@@ -2005,17 +2015,20 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
9119d9
 static int
9119d9
 qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
9119d9
                                            const char *dev_name,
9119d9
+                                           int depth,
9119d9
                                            virHashTablePtr stats,
9119d9
-                                           bool backingChain ATTRIBUTE_UNUSED)
9119d9
+                                           bool backingChain)
9119d9
 {
9119d9
     qemuBlockStatsPtr bstats;
9119d9
     int ret = -1;
9119d9
+    char *entry_name = qemuDomainStorageAlias(dev_name, depth);
9119d9
+    virJSONValuePtr backing;
9119d9
 
9119d9
-    if (!(bstats = virHashLookup(stats, dev_name))) {
9119d9
+    if (!(bstats = virHashLookup(stats, entry_name))) {
9119d9
         if (VIR_ALLOC(bstats) < 0)
9119d9
             goto cleanup;
9119d9
 
9119d9
-        if (virHashAddEntry(stats, dev_name, bstats) < 0) {
9119d9
+        if (virHashAddEntry(stats, entry_name, bstats) < 0) {
9119d9
             VIR_FREE(bstats);
9119d9
             goto cleanup;
9119d9
         }
9119d9
@@ -2032,7 +2045,18 @@ qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
9119d9
     if (virJSONValueObjectGetNumberUlong(image, "actual-size",
9119d9
                                          &bstats->physical) < 0)
9119d9
         bstats->physical = bstats->capacity;
9119d9
+
9119d9
+    if (backingChain &&
9119d9
+        (backing = virJSONValueObjectGet(image, "backing-image"))) {
9119d9
+        ret = qemuMonitorJSONBlockStatsUpdateCapacityOne(backing,
9119d9
+                                                         dev_name,
9119d9
+                                                         depth + 1,
9119d9
+                                                         stats,
9119d9
+                                                         true);
9119d9
+    }
9119d9
+
9119d9
  cleanup:
9119d9
+    VIR_FREE(entry_name);
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
@@ -2085,15 +2109,13 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
9119d9
             goto cleanup;
9119d9
         }
9119d9
 
9119d9
-        if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
9119d9
-            dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
9119d9
-
9119d9
         /* drive may be empty */
9119d9
         if (!(inserted = virJSONValueObjectGet(dev, "inserted")) ||
9119d9
             !(image = virJSONValueObjectGet(inserted, "image")))
9119d9
             continue;
9119d9
 
9119d9
-        if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, stats,
9119d9
+        if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, 0,
9119d9
+                                                       stats,
9119d9
                                                        backingChain) < 0)
9119d9
             goto cleanup;
9119d9
     }
9119d9
-- 
9119d9
2.2.0
9119d9