qemu: monitor: Retrieve blockstats also by qdev and node-names

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2018-08-03 16:22:19 +02:00
parent b222ce3075
commit d703306cd9
1 changed files with 50 additions and 5 deletions

View File

@ -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 static int
qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev, qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
const char *dev_name, const char *dev_name,
@ -2342,18 +2364,38 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
qemuBlockStatsPtr bstats = NULL; qemuBlockStatsPtr bstats = NULL;
int ret = -1; int ret = -1;
int nstats = 0; int nstats = 0;
char *entry_name = qemuDomainStorageAlias(dev_name, depth); const char *qdevname = NULL;
const char *nodename = NULL;
char *devicename = NULL;
virJSONValuePtr backing; virJSONValuePtr backing;
if (!entry_name) if (dev_name &&
!(devicename = qemuDomainStorageAlias(dev_name, depth)))
goto cleanup; 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))) if (!(bstats = qemuMonitorJSONBlockStatsCollectData(dev, &nstats)))
goto cleanup; 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; goto cleanup;
bstats = NULL;
if (backingChain && if (backingChain &&
(backing = virJSONValueObjectGetObject(dev, "backing")) && (backing = virJSONValueObjectGetObject(dev, "backing")) &&
@ -2364,7 +2406,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
ret = nstats; ret = nstats;
cleanup: cleanup:
VIR_FREE(bstats); VIR_FREE(bstats);
VIR_FREE(entry_name); VIR_FREE(devicename);
return ret; return ret;
} }
@ -2426,6 +2468,9 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto cleanup; goto cleanup;
} }
if (*dev_name == '\0')
dev_name = NULL;
rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash, rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
backingChain); backingChain);