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 <natto@weirdnatto.in>
This commit is contained in:
Amneesh Singh 2022-09-07 16:04:18 +05:30 committed by Martin Kletzander
parent d057b0bfc4
commit e89acdbc3b
4 changed files with 168 additions and 0 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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:

View File

@ -812,6 +812,10 @@ int
qemuMonitorJSONMigrateRecover(qemuMonitor *mon,
const char *uri);
GHashTable *
qemuMonitorJSONQueryStatsSchema(qemuMonitor *mon,
qemuMonitorQueryStatsProviderType provider_type);
virJSONValue *
qemuMonitorJSONQueryStats(qemuMonitor *mon,
qemuMonitorQueryStatsTargetType target,