123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*
- * QMP commands related to stats
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version.
- */
- #include "qemu/osdep.h"
- #include "system/stats.h"
- #include "qapi/qapi-commands-stats.h"
- #include "qemu/queue.h"
- #include "qapi/error.h"
- typedef struct StatsCallbacks {
- StatsProvider provider;
- StatRetrieveFunc *stats_cb;
- SchemaRetrieveFunc *schemas_cb;
- QTAILQ_ENTRY(StatsCallbacks) next;
- } StatsCallbacks;
- static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
- QTAILQ_HEAD_INITIALIZER(stats_callbacks);
- void add_stats_callbacks(StatsProvider provider,
- StatRetrieveFunc *stats_fn,
- SchemaRetrieveFunc *schemas_fn)
- {
- StatsCallbacks *entry = g_new(StatsCallbacks, 1);
- entry->provider = provider;
- entry->stats_cb = stats_fn;
- entry->schemas_cb = schemas_fn;
- QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next);
- }
- static bool invoke_stats_cb(StatsCallbacks *entry,
- StatsResultList **stats_results,
- StatsFilter *filter, StatsRequest *request,
- Error **errp)
- {
- ERRP_GUARD();
- strList *targets = NULL;
- strList *names = NULL;
- if (request) {
- if (request->provider != entry->provider) {
- return true;
- }
- if (request->has_names && !request->names) {
- return true;
- }
- names = request->has_names ? request->names : NULL;
- }
- 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;
- case STATS_TARGET_CRYPTODEV:
- break;
- default:
- abort();
- }
- entry->stats_cb(stats_results, filter->target, names, targets, errp);
- if (*errp) {
- qapi_free_StatsResultList(*stats_results);
- *stats_results = NULL;
- return false;
- }
- return true;
- }
- StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp)
- {
- StatsResultList *stats_results = NULL;
- StatsCallbacks *entry;
- StatsRequestList *request;
- QTAILQ_FOREACH(entry, &stats_callbacks, next) {
- if (filter->has_providers) {
- for (request = filter->providers; request; request = request->next) {
- if (!invoke_stats_cb(entry, &stats_results, filter,
- request->value, errp)) {
- break;
- }
- }
- } else {
- if (!invoke_stats_cb(entry, &stats_results, filter, NULL, errp)) {
- break;
- }
- }
- }
- return stats_results;
- }
- StatsSchemaList *qmp_query_stats_schemas(bool has_provider,
- StatsProvider provider,
- Error **errp)
- {
- ERRP_GUARD();
- StatsSchemaList *stats_results = NULL;
- StatsCallbacks *entry;
- QTAILQ_FOREACH(entry, &stats_callbacks, next) {
- if (!has_provider || provider == entry->provider) {
- entry->schemas_cb(&stats_results, errp);
- if (*errp) {
- qapi_free_StatsSchemaList(stats_results);
- return NULL;
- }
- }
- }
- return stats_results;
- }
- void add_stats_entry(StatsResultList **stats_results, StatsProvider provider,
- const char *qom_path, StatsList *stats_list)
- {
- StatsResult *entry = g_new0(StatsResult, 1);
- entry->provider = provider;
- entry->qom_path = g_strdup(qom_path);
- entry->stats = stats_list;
- QAPI_LIST_PREPEND(*stats_results, entry);
- }
- void add_stats_schema(StatsSchemaList **schema_results,
- StatsProvider provider, StatsTarget target,
- StatsSchemaValueList *stats_list)
- {
- StatsSchema *entry = g_new0(StatsSchema, 1);
- entry->provider = provider;
- entry->target = target;
- entry->stats = stats_list;
- 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;
- }
|