mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 09:55:18 +00:00
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: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
7b11f5e554
commit
b1802714da
@ -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
|
int
|
||||||
qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
@ -376,6 +376,7 @@ int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
|
|||||||
int qemuDomainStorageFileInit(virQEMUDriverPtr driver,
|
int qemuDomainStorageFileInit(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virStorageSourcePtr src);
|
virStorageSourcePtr src);
|
||||||
|
char *qemuDomainStorageAlias(const char *device, int depth);
|
||||||
|
|
||||||
int qemuDomainCleanupAdd(virDomainObjPtr vm,
|
int qemuDomainCleanupAdd(virDomainObjPtr vm,
|
||||||
qemuDomainCleanupCallback cb);
|
qemuDomainCleanupCallback cb);
|
||||||
|
@ -1696,13 +1696,18 @@ qemuMonitorJSONDevGetBlockExtent(virJSONValuePtr dev,
|
|||||||
static int
|
static int
|
||||||
qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
|
qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
|
||||||
const char *dev_name,
|
const char *dev_name,
|
||||||
|
int depth,
|
||||||
virHashTablePtr hash,
|
virHashTablePtr hash,
|
||||||
bool backingChain ATTRIBUTE_UNUSED)
|
bool backingChain)
|
||||||
{
|
{
|
||||||
qemuBlockStatsPtr bstats = NULL;
|
qemuBlockStatsPtr bstats = NULL;
|
||||||
virJSONValuePtr stats;
|
virJSONValuePtr stats;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
char *entry_name = qemuDomainStorageAlias(dev_name, depth);
|
||||||
|
virJSONValuePtr backing;
|
||||||
|
|
||||||
|
if (!entry_name)
|
||||||
|
goto cleanup;
|
||||||
if (VIR_ALLOC(bstats) < 0)
|
if (VIR_ALLOC(bstats) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1778,12 +1783,20 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
|
|||||||
/* it's ok to not have this information here. Just skip silently. */
|
/* it's ok to not have this information here. Just skip silently. */
|
||||||
qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
|
qemuMonitorJSONDevGetBlockExtent(dev, &bstats->wr_highest_offset);
|
||||||
|
|
||||||
if (virHashAddEntry(hash, dev_name, bstats) < 0)
|
if (virHashAddEntry(hash, entry_name, bstats) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
bstats = NULL;
|
bstats = NULL;
|
||||||
|
|
||||||
|
if (backingChain &&
|
||||||
|
(backing = virJSONValueObjectGet(dev, "backing")) &&
|
||||||
|
qemuMonitorJSONGetOneBlockStatsInfo(backing, dev_name, depth + 1,
|
||||||
|
hash, true) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(bstats);
|
VIR_FREE(bstats);
|
||||||
|
VIR_FREE(entry_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1838,10 +1851,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
|
if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
|
||||||
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
|
|
||||||
|
|
||||||
if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, hash,
|
|
||||||
backingChain) < 0)
|
backingChain) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1862,17 +1872,20 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
|||||||
static int
|
static int
|
||||||
qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
|
qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
|
||||||
const char *dev_name,
|
const char *dev_name,
|
||||||
|
int depth,
|
||||||
virHashTablePtr stats,
|
virHashTablePtr stats,
|
||||||
bool backingChain ATTRIBUTE_UNUSED)
|
bool backingChain)
|
||||||
{
|
{
|
||||||
qemuBlockStatsPtr bstats;
|
qemuBlockStatsPtr bstats;
|
||||||
int ret = -1;
|
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)
|
if (VIR_ALLOC(bstats) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virHashAddEntry(stats, dev_name, bstats) < 0) {
|
if (virHashAddEntry(stats, entry_name, bstats) < 0) {
|
||||||
VIR_FREE(bstats);
|
VIR_FREE(bstats);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1889,7 +1902,18 @@ qemuMonitorJSONBlockStatsUpdateCapacityOne(virJSONValuePtr image,
|
|||||||
if (virJSONValueObjectGetNumberUlong(image, "actual-size",
|
if (virJSONValueObjectGetNumberUlong(image, "actual-size",
|
||||||
&bstats->physical) < 0)
|
&bstats->physical) < 0)
|
||||||
bstats->physical = bstats->capacity;
|
bstats->physical = bstats->capacity;
|
||||||
|
|
||||||
|
if (backingChain &&
|
||||||
|
(backing = virJSONValueObjectGet(image, "backing-image"))) {
|
||||||
|
ret = qemuMonitorJSONBlockStatsUpdateCapacityOne(backing,
|
||||||
|
dev_name,
|
||||||
|
depth + 1,
|
||||||
|
stats,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
VIR_FREE(entry_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1942,15 +1966,13 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX))
|
|
||||||
dev_name += strlen(QEMU_DRIVE_HOST_PREFIX);
|
|
||||||
|
|
||||||
/* drive may be empty */
|
/* drive may be empty */
|
||||||
if (!(inserted = virJSONValueObjectGet(dev, "inserted")) ||
|
if (!(inserted = virJSONValueObjectGet(dev, "inserted")) ||
|
||||||
!(image = virJSONValueObjectGet(inserted, "image")))
|
!(image = virJSONValueObjectGet(inserted, "image")))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, stats,
|
if (qemuMonitorJSONBlockStatsUpdateCapacityOne(image, dev_name, 0,
|
||||||
|
stats,
|
||||||
backingChain) < 0)
|
backingChain) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user