From e89acdbc3bbada2f3c1a591278bc975ddee2d5a9 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Wed, 7 Sep 2022 16:04:18 +0530 Subject: [PATCH] qemu_monitor: add qemuMonitorQueryStatsSchema Related: https://gitlab.com/libvirt/libvirt/-/issues/276 This patch adds a simple API for "query-stats-schemas" QMP command Signed-off-by: Amneesh Singh --- src/qemu/qemu_monitor.c | 29 +++++++++++ src/qemu/qemu_monitor.h | 37 ++++++++++++++ src/qemu/qemu_monitor_json.c | 98 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++ 4 files changed, 168 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 5eba154d96..9e54bb180e 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4354,6 +4354,35 @@ qemuMonitorQueryStatsProviderNew(qemuMonitorQueryStatsProviderType provider_type } +VIR_ENUM_IMPL(qemuMonitorQueryStatsUnit, + QEMU_MONITOR_QUERY_STATS_UNIT_LAST, + "bytes", + "seconds", + "cycles", + "boolean", +); + + +VIR_ENUM_IMPL(qemuMonitorQueryStatsType, + QEMU_MONITOR_QUERY_STATS_TYPE_LAST, + "cumulative", + "instant", + "peak", + "linear-histogram", + "log2-histogram", +); + + +GHashTable * +qemuMonitorQueryStatsSchema(qemuMonitor *mon, + qemuMonitorQueryStatsProviderType provider_type) +{ + QEMU_CHECK_MONITOR_NULL(mon); + + return qemuMonitorJSONQueryStatsSchema(mon, provider_type); +} + + virJSONValue * qemuMonitorQueryStats(qemuMonitor *mon, qemuMonitorQueryStatsTargetType target, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 4fead0a998..8ca68301b4 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1517,6 +1517,43 @@ qemuMonitorQueryStatsProviderNew(qemuMonitorQueryStatsProviderType provider_type G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMonitorQueryStatsProvider, qemuMonitorQueryStatsProviderFree); +typedef enum { + QEMU_MONITOR_QUERY_STATS_UNIT_BYTES, + QEMU_MONITOR_QUERY_STATS_UNIT_SECONDS, + QEMU_MONITOR_QUERY_STATS_UNIT_CYCLES, + QEMU_MONITOR_QUERY_STATS_UNIT_BOOLEAN, + + QEMU_MONITOR_QUERY_STATS_UNIT_LAST +} qemuMonitorQueryStatsUnitType; + +VIR_ENUM_DECL(qemuMonitorQueryStatsUnit); + +typedef enum { + QEMU_MONITOR_QUERY_STATS_TYPE_CUMULATIVE, + QEMU_MONITOR_QUERY_STATS_TYPE_INSTANT, + QEMU_MONITOR_QUERY_STATS_TYPE_PEAK, + QEMU_MONITOR_QUERY_STATS_TYPE_LINEAR_HISTOGRAM, + QEMU_MONITOR_QUERY_STATS_TYPE_LOG2_HISTOGRAM, + + QEMU_MONITOR_QUERY_STATS_TYPE_LAST +} qemuMonitorQueryStatsTypeType; + +VIR_ENUM_DECL(qemuMonitorQueryStatsType); + +typedef struct _qemuMonitorQueryStatsSchemaData qemuMonitorQueryStatsSchemaData; +struct _qemuMonitorQueryStatsSchemaData { + qemuMonitorQueryStatsTargetType target; + qemuMonitorQueryStatsUnitType unit; + qemuMonitorQueryStatsTypeType type; + unsigned int bucket_size; + int base; + int exponent; +}; + +GHashTable * +qemuMonitorQueryStatsSchema(qemuMonitor *mon, + qemuMonitorQueryStatsProviderType provider_type); + virJSONValue * qemuMonitorQueryStats(qemuMonitor *mon, qemuMonitorQueryStatsTargetType target, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index f54b4609a9..2bd159bc98 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -8567,6 +8567,104 @@ qemuMonitorJSONMigrateRecover(qemuMonitor *mon, return qemuMonitorJSONCheckError(cmd, reply); } +static GHashTable * +qemuMonitorJSONExtractQueryStatsSchema(virJSONValue *json) +{ + g_autoptr(GHashTable) schema = virHashNew(g_free); + size_t i; + + for (i = 0; i < virJSONValueArraySize(json); i++) { + virJSONValue *obj, *stats; + const char *target_str; + int target; + size_t j; + + obj = virJSONValueArrayGet(json, i); + + if (!virJSONValueIsObject(obj)) + continue; + + stats = virJSONValueObjectGetArray(obj, "stats"); + + if (!virJSONValueIsArray(stats)) + continue; + + target_str = virJSONValueObjectGetString(obj, "target"); + target = qemuMonitorQueryStatsTargetTypeFromString(target_str); + + for (j = 0; j < virJSONValueArraySize(stats); j++) { + virJSONValue *stat = virJSONValueArrayGet(stats, j); + const char *name = NULL; + const char *tmp = NULL; + qemuMonitorQueryStatsSchemaData *data = NULL; + int type = -1; + int unit = -1; + + if (!virJSONValueIsObject(stat)) + continue; + + name = virJSONValueObjectGetString(stat, "name"); + if (!name) + continue; + + tmp = virJSONValueObjectGetString(stat, "type"); + type = qemuMonitorQueryStatsTypeTypeFromString(tmp); + + tmp = virJSONValueObjectGetString(stat, "unit"); + unit = qemuMonitorQueryStatsUnitTypeFromString(tmp); + + data = g_new0(qemuMonitorQueryStatsSchemaData, 1); + data->target = (target == -1) ? QEMU_MONITOR_QUERY_STATS_TARGET_LAST : target; + data->type = (type == -1) ? QEMU_MONITOR_QUERY_STATS_TYPE_LAST : type; + data->unit = (unit == -1) ? QEMU_MONITOR_QUERY_STATS_UNIT_LAST : unit; + + if (virJSONValueObjectGetNumberInt(stat, "base", &data->base) < 0 || + virJSONValueObjectGetNumberInt(stat, "exponent", &data->exponent) < 0) { + /* + * Base of zero means that there is simply no scale, data->exponent + * is set to 0 just for safety measures + */ + data->base = 0; + data->exponent = 0; + } + + if (data->type == QEMU_MONITOR_QUERY_STATS_TYPE_LINEAR_HISTOGRAM && + virJSONValueObjectGetNumberUint(stat, "bucket-size", &data->bucket_size) < 0) + data->bucket_size = 0; + + virHashAddEntry(schema, name, data); + } + } + + return g_steal_pointer(&schema); +} + +GHashTable * +qemuMonitorJSONQueryStatsSchema(qemuMonitor *mon, + qemuMonitorQueryStatsProviderType provider_type) +{ + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; + virJSONValue *ret; + + const char *type_str = qemuMonitorQueryStatsProviderTypeToString(provider_type); + + if (!(cmd = qemuMonitorJSONMakeCommand("query-stats-schemas", + "S:provider", type_str, + NULL))) + return NULL; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return NULL; + + if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0) + return NULL; + + ret = virJSONValueObjectGetArray(reply, "return"); + + return qemuMonitorJSONExtractQueryStatsSchema(ret); +} + /** * qemuMonitorJSONQueryStats: diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index f14d0b5bae..c0abc9dd4f 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -812,6 +812,10 @@ int qemuMonitorJSONMigrateRecover(qemuMonitor *mon, const char *uri); +GHashTable * +qemuMonitorJSONQueryStatsSchema(qemuMonitor *mon, + qemuMonitorQueryStatsProviderType provider_type); + virJSONValue * qemuMonitorJSONQueryStats(qemuMonitor *mon, qemuMonitorQueryStatsTargetType target,