For use with -blockdev we need to be able to retrieve the stats by
'qdev' for the frontend device stats since 'device' will be NULL.
Additionally so that we can report the highest written offset we need to
also be able to access them by node-name for backing chain purposes.
In cases when 'device' is empty it does not make sense to gather them.
Allow arranging the stats simultaneously in all the above dimensions.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_monitor_json.c | 55 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 105f6f78ac..24e3d61699 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2324,6 +2324,28 @@ qemuMonitorJSONBlockStatsCollectData(virJSONValuePtr dev,
}
+static int
+qemuMonitorJSONAddOneBlockStatsInfo(qemuBlockStatsPtr bstats,
+ const char *name,
+ virHashTablePtr stats)
+{
+ qemuBlockStatsPtr copy = NULL;
+
+ if (VIR_ALLOC(copy) < 0)
+ return -1;
+
+ if (bstats)
+ *copy = *bstats;
+
+ if (virHashAddEntry(stats, name, copy) < 0) {
+ VIR_FREE(copy);
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
const char *dev_name,
@@ -2334,18 +2356,38 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
qemuBlockStatsPtr bstats = NULL;
int ret = -1;
int nstats = 0;
- char *entry_name = qemuDomainStorageAlias(dev_name, depth);
+ const char *qdevname = NULL;
+ const char *nodename = NULL;
+ char *devicename = NULL;
virJSONValuePtr backing;
- if (!entry_name)
+ if (dev_name &&
+ !(devicename = qemuDomainStorageAlias(dev_name, depth)))
goto cleanup;
+ qdevname = virJSONValueObjectGetString(dev, "qdev");
+ nodename = virJSONValueObjectGetString(dev, "node-name");
+
+ if (!devicename && !qdevname && !nodename) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("blockstats device entry was not in expected
format"));
+ goto cleanup;
+ }
+
if (!(bstats = qemuMonitorJSONBlockStatsCollectData(dev, &nstats)))
goto cleanup;
- if (virHashAddEntry(hash, entry_name, bstats) < 0)
+ if (devicename &&
+ qemuMonitorJSONAddOneBlockStatsInfo(bstats, devicename, hash) < 0)
+ goto cleanup;
+
+ if (qdevname &&
+ qemuMonitorJSONAddOneBlockStatsInfo(bstats, qdevname, hash) < 0)
+ goto cleanup;
+
+ if (nodename &&
+ qemuMonitorJSONAddOneBlockStatsInfo(bstats, nodename, hash) < 0)
goto cleanup;
- bstats = NULL;
if (backingChain &&
(backing = virJSONValueObjectGetObject(dev, "backing")) &&
@@ -2356,7 +2398,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
ret = nstats;
cleanup:
VIR_FREE(bstats);
- VIR_FREE(entry_name);
+ VIR_FREE(devicename);
return ret;
}
@@ -2418,6 +2460,9 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto cleanup;
}
+ if (*dev_name == '\0')
+ dev_name = NULL;
+
rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
backingChain);
--
2.16.2