For use with -blockdev we need to be able to retrieve the stats by 'qdev' for the frontend device stats since 'device' will be empty. Note that for non-blockdev case qdev and 'device' with 'drive-' skipped would be the same. 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@xxxxxxxxxx> --- 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 3351d405f3..670147ddb6 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2332,6 +2332,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, @@ -2342,18 +2364,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 && STRNEQ_NULLABLE(qdevname, devicename) && + qemuMonitorJSONAddOneBlockStatsInfo(bstats, qdevname, hash) < 0) + goto cleanup; + + if (nodename && + qemuMonitorJSONAddOneBlockStatsInfo(bstats, nodename, hash) < 0) goto cleanup; - bstats = NULL; if (backingChain && (backing = virJSONValueObjectGetObject(dev, "backing")) && @@ -2364,7 +2406,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev, ret = nstats; cleanup: VIR_FREE(bstats); - VIR_FREE(entry_name); + VIR_FREE(devicename); return ret; } @@ -2426,6 +2468,9 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, goto cleanup; } + if (*dev_name == '\0') + dev_name = NULL; + rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash, backingChain); -- 2.16.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list