On Thu, Aug 18, 2022 at 08:47:18AM +0530, Amneesh Singh wrote:
Related: https://gitlab.com/libvirt/libvirt/-/issues/276 This patch adds an API for the "query-stats" QMP command. The query returns a JSON containing the statistics based on the target, which can either be vCPU or VM, and the providers. The API deserializes the query result into an array of GHashMaps, which can later be used to extract all the query statistics. GHashMaps are used to avoid traversing the entire array to find the statistics you are looking for. This would be a singleton array if the target is a VM since the returned JSON is also a singleton array in that case. Signed-off-by: Amneesh Singh <natto@xxxxxxxxxxxxx> --- src/qemu/qemu_monitor.c | 117 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 48 ++++++++++++++ src/qemu/qemu_monitor_json.c | 91 +++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++ 4 files changed, 262 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 4739810c9b..1488f7481f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4297,3 +4297,120 @@ qemuMonitorGetMigrationBlockers(qemuMonitor *mon, return qemuMonitorJSONGetMigrationBlockers(mon, blockers); } + + +VIR_ENUM_IMPL(qemuMonitorQueryStatsTarget, + QEMU_MONITOR_QUERY_STATS_TARGET_LAST, + "vm", + "vcpu", +); + + +VIR_ENUM_IMPL(qemuMonitorQueryStatsName, + QEMU_MONITOR_QUERY_STATS_NAME_LAST, + "halt_poll_success_ns", + "halt_poll_fail_ns", +); + + +VIR_ENUM_IMPL(qemuMonitorQueryStatsProvider, + QEMU_MONITOR_QUERY_STATS_PROVIDER_LAST, + "kvm", +); + + +void +qemuMonitorQueryStatsProviderFree(qemuMonitorQueryStatsProvider *provider) +{ + virBitmapFree(provider->names); + g_free(provider); +} + + +qemuMonitorQueryStatsProvider * +qemuMonitorQueryStatsProviderNew(qemuMonitorQueryStatsProviderType provider_type, + ...) +{ + qemuMonitorQueryStatsProvider *provider = g_new0(qemuMonitorQueryStatsProvider, 1); + qemuMonitorQueryStatsNameType stat; + va_list name_list; + + /* + * This can be lowered later in case of the enum getting quite large, hence + * the virBitmapSetExpand below which also incidently makes this function + * non-fallible. + */ + provider->names = virBitmapNew(QEMU_MONITOR_QUERY_STATS_NAME_LAST); + provider->type = provider_type; + + va_start(name_list, provider_type); + + while ((stat = va_arg(name_list, qemuMonitorQueryStatsNameType)) != + QEMU_MONITOR_QUERY_STATS_NAME_LAST) + virBitmapSetBitExpand(provider->names, stat); + + va_end(name_list); + + return provider; +} + + +virJSONValue * +qemuMonitorQueryStats(qemuMonitor *mon, + qemuMonitorQueryStatsTargetType target, + char **vcpus, + GPtrArray *providers) +{ + VIR_DEBUG("target=%u vcpus=%p providers=%p", target, vcpus, providers); + + QEMU_CHECK_MONITOR_NULL(mon); + + if (target != QEMU_MONITOR_QUERY_STATS_TARGET_VCPU && vcpus) + return NULL; + + return qemuMonitorJSONQueryStats(mon, target, vcpus, providers); +} + + +/** + * qemuMonitorExtractQueryStats: + * @info: One of the array members returned by qemuMonitorQueryStat + * + * Converts all the statistics into a GHashTable similar to virQEMU + * except only object with the key "value" is stored as the value i + * + * Returns NULL on failure. + */ +GHashTable * +qemuMonitorExtractQueryStats(virJSONValue *info) +{ + g_autoptr(GHashTable) hash_table = NULL; + virJSONValue *stats = NULL; + size_t i; + + if (!virJSONValueIsObject(info)) + return NULL; + + stats = virJSONValueObjectGetArray(info, "stats");
I added a check that stats is not NULL here. Reviewed-by: Martin Kletzander <mkletzan@xxxxxxxxxx>
Attachment:
signature.asc
Description: PGP signature