qmp: add filtering of statistics by target vCPU
Introduce a simple filtering of statistics, that allows to retrieve statistics for a subset of the guest vCPUs. This will be used for example by the HMP monitor, in order to retrieve the statistics for the currently selected CPU. Example: { "execute": "query-stats", "arguments": { "target": "vcpu", "vcpus": [ "/machine/unattached/device[2]", "/machine/unattached/device[4]" ] } } Extracted from a patch by Mark Kanda. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
cc01a3f4ca
commit
467ef823d8
@ -2311,7 +2311,8 @@ bool kvm_dirty_ring_enabled(void)
|
|||||||
return kvm_state->kvm_dirty_ring_size ? true : false;
|
return kvm_state->kvm_dirty_ring_size ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void query_stats_cb(StatsResultList **result, StatsTarget target, Error **errp);
|
static void query_stats_cb(StatsResultList **result, StatsTarget target,
|
||||||
|
strList *targets, Error **errp);
|
||||||
static void query_stats_schemas_cb(StatsSchemaList **result, Error **errp);
|
static void query_stats_schemas_cb(StatsSchemaList **result, Error **errp);
|
||||||
|
|
||||||
static int kvm_init(MachineState *ms)
|
static int kvm_init(MachineState *ms)
|
||||||
@ -4038,7 +4039,8 @@ static void query_stats_schema_vcpu(CPUState *cpu, run_on_cpu_data data)
|
|||||||
close(stats_fd);
|
close(stats_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void query_stats_cb(StatsResultList **result, StatsTarget target, Error **errp)
|
static void query_stats_cb(StatsResultList **result, StatsTarget target,
|
||||||
|
strList *targets, Error **errp)
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
@ -4062,6 +4064,9 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target, Error *
|
|||||||
stats_args.result.stats = result;
|
stats_args.result.stats = result;
|
||||||
stats_args.errp = errp;
|
stats_args.errp = errp;
|
||||||
CPU_FOREACH(cpu) {
|
CPU_FOREACH(cpu) {
|
||||||
|
if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
run_on_cpu(cpu, query_stats_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args));
|
run_on_cpu(cpu, query_stats_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "qapi/qapi-types-stats.h"
|
#include "qapi/qapi-types-stats.h"
|
||||||
|
|
||||||
typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target,
|
typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target,
|
||||||
Error **errp);
|
strList *targets, Error **errp);
|
||||||
typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp);
|
typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,4 +31,13 @@ void add_stats_entry(StatsResultList **, StatsProvider, const char *id,
|
|||||||
void add_stats_schema(StatsSchemaList **, StatsProvider, StatsTarget,
|
void add_stats_schema(StatsSchemaList **, StatsProvider, StatsTarget,
|
||||||
StatsSchemaValueList *);
|
StatsSchemaValueList *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* True if a string matches the filter passed to the stats_fn callabck,
|
||||||
|
* false otherwise.
|
||||||
|
*
|
||||||
|
* Note that an empty list means no filtering, i.e. all strings will
|
||||||
|
* return true.
|
||||||
|
*/
|
||||||
|
bool apply_str_list_filter(const char *string, strList *list);
|
||||||
|
|
||||||
#endif /* STATS_H */
|
#endif /* STATS_H */
|
||||||
|
@ -468,9 +468,26 @@ static bool invoke_stats_cb(StatsCallbacks *entry,
|
|||||||
StatsFilter *filter,
|
StatsFilter *filter,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
strList *targets = NULL;
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
|
|
||||||
entry->stats_cb(stats_results, filter->target, errp);
|
switch (filter->target) {
|
||||||
|
case STATS_TARGET_VM:
|
||||||
|
break;
|
||||||
|
case STATS_TARGET_VCPU:
|
||||||
|
if (filter->u.vcpu.has_vcpus) {
|
||||||
|
if (!filter->u.vcpu.vcpus) {
|
||||||
|
/* No targets allowed? Return no statistics. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
targets = filter->u.vcpu.vcpus;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->stats_cb(stats_results, filter->target, targets, errp);
|
||||||
if (*errp) {
|
if (*errp) {
|
||||||
qapi_free_StatsResultList(*stats_results);
|
qapi_free_StatsResultList(*stats_results);
|
||||||
*stats_results = NULL;
|
*stats_results = NULL;
|
||||||
@ -536,3 +553,18 @@ void add_stats_schema(StatsSchemaList **schema_results,
|
|||||||
entry->stats = stats_list;
|
entry->stats = stats_list;
|
||||||
QAPI_LIST_PREPEND(*schema_results, entry);
|
QAPI_LIST_PREPEND(*schema_results, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool apply_str_list_filter(const char *string, strList *list)
|
||||||
|
{
|
||||||
|
strList *str_list = NULL;
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (str_list = list; str_list; str_list = str_list->next) {
|
||||||
|
if (g_str_equal(string, str_list->value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -70,15 +70,29 @@
|
|||||||
'data': [ 'vm', 'vcpu' ] }
|
'data': [ 'vm', 'vcpu' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @StatsFilter:
|
# @StatsVCPUFilter:
|
||||||
#
|
#
|
||||||
# The arguments to the query-stats command; specifies a target for which to
|
# @vcpus: list of QOM paths for the desired vCPU objects.
|
||||||
# request statistics.
|
|
||||||
#
|
#
|
||||||
# Since: 7.1
|
# Since: 7.1
|
||||||
##
|
##
|
||||||
{ 'struct': 'StatsFilter',
|
{ 'struct': 'StatsVCPUFilter',
|
||||||
'data': { 'target': 'StatsTarget' } }
|
'data': { '*vcpus': [ 'str' ] } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @StatsFilter:
|
||||||
|
#
|
||||||
|
# The arguments to the query-stats command; specifies a target for which to
|
||||||
|
# request statistics and optionally the required subset of information for
|
||||||
|
# that target:
|
||||||
|
# - which vCPUs to request statistics for
|
||||||
|
#
|
||||||
|
# Since: 7.1
|
||||||
|
##
|
||||||
|
{ 'union': 'StatsFilter',
|
||||||
|
'base': { 'target': 'StatsTarget' },
|
||||||
|
'discriminator': 'target',
|
||||||
|
'data': { 'vcpu': 'StatsVCPUFilter' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @StatsValue:
|
# @StatsValue:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user