提交 b1802714 编写于 作者: E Eric Blake

getstats: perform recursion in monitor collection

When requested in a later patch, the QMP command results are now
examined recursively.  As qemu_driver will eventually have to
read items out of the hash table as stored by this patch, the
computation of backing alias string is done in a shared location.

* src/qemu/qemu_domain.h (qemuDomainStorageAlias): New prototype.
* src/qemu/qemu_domain.c (qemuDomainStorageAlias): Implement it.
* src/qemu/qemu_monitor_json.c
(qemuMonitorJSONGetOneBlockStatsInfo)
(qemuMonitorJSONBlockStatsUpdateCapacityOne): Perform recursion.
(qemuMonitorJSONGetAllBlockStatsInfo)
(qemuMonitorJSONBlockStatsUpdateCapacity): Update callers.
Signed-off-by: NEric Blake <eblake@redhat.com>
上级 7b11f5e5
......@@ -2694,6 +2694,22 @@ qemuDomainStorageFileInit(virQEMUDriverPtr driver,
}
char *
qemuDomainStorageAlias(const char *device, int depth)
{
char *alias;
if (STRPREFIX(device, QEMU_DRIVE_HOST_PREFIX))
device += strlen(QEMU_DRIVE_HOST_PREFIX);
if (!depth)
ignore_value(VIR_STRDUP(alias, device));
else
ignore_value(virAsprintf(&alias, "%s.%d", device, depth));
return alias;
}
int
qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
virDomainObjPtr vm,
......
......@@ -376,6 +376,7 @@ int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
int qemuDomainStorageFileInit(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virStorageSourcePtr src);
char *qemuDomainStorageAlias(const char *device, int depth);
int qemuDomainCleanupAdd(virDomainObjPtr vm,
qemuDomainCleanupCallback cb);
......
......@@ -1696,13 +1696,18 @@ qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
static int
qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
const char *dev_name,
int depth,
virHashTablePtr hash,
bool backingChain ATTRIBUTE_UNUSED)
bool backingChain)
{
qemuBlockStatsPtr bstats = NULL;
virJSONValuePtr stats;
int ret = -1;
char *entry_name = qemuDomainStorageAlias(dev_name, depth);
virJSONValuePtr backing;
if (!entry_name)
goto cleanup;
if (VIR_ALLOC(bstats) < 0)
goto cleanup;
......@@ -1778,12 +1783,20 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
/* it's ok to not have this information here. Just skip silently. */
qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
if (virHashAddEntry(hash, dev_name, bstats) < 0)
if (virHashAddEntry(hash, entry_name, bstats) < 0)
goto cleanup;
bstats = NULL;
if (backingChain &&
(backing = virJSONValueObjectGet(dev, "backing")) &&
qemuMonitorJSONGetOneBlockStatsInfo(backing, dev_name, depth + 1,
hash, true) < 0)
goto cleanup;
ret = 0;
cleanup:
VIR_FREE(bstats);
VIR_FREE(entry_name);
return ret;
}
......@@ -1838,10 +1851,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto cleanup;
}
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, hash,
if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
backingChain) < 0)
goto cleanup;
......@@ -1862,17 +1872,20 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
static int
qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
const char *dev_name,
int depth,
virHashTablePtr stats,
bool backingChain ATTRIBUTE_UNUSED)
bool backingChain)
{
qemuBlockStatsPtr bstats;
int ret = -1;
char *entry_name = qemuDomainStorageAlias(dev_name, depth);
virJSONValuePtr backing;
if (!(bstats = virHashLookup(stats, dev_name))) {
if (!(bstats = virHashLookup(stats, entry_name))) {
if (VIR_ALLOC(bstats) < 0)
goto cleanup;
if (virHashAddEntry(stats, dev_name, bstats) < 0) {
if (virHashAddEntry(stats, entry_name, bstats) < 0) {
VIR_FREE(bstats);
goto cleanup;
}
......@@ -1889,7 +1902,18 @@ qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
if (virJSONValueObjectGetNumberUlong(image, "actual-size",
&bstats->physical) < 0)
bstats->physical = bstats->capacity;
if (backingChain &&
(backing = virJSONValueObjectGet(image, "backing-image"))) {
ret = qemuMonitorJSONBlockStatsUpdateCapacityOne(backing,
dev_name,
depth + 1,
stats,
true);
}
cleanup:
VIR_FREE(entry_name);
return ret;
}
......@@ -1942,15 +1966,13 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
goto cleanup;
}
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
/* drive may be empty */
if (!(inserted = virJSONValueObjectGet(dev, "inserted")) ||
!(image = virJSONValueObjectGet(inserted, "image")))
continue;
if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, stats,
if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, 0,
stats,
backingChain) < 0)
goto cleanup;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册