blk_iostatus_reset(blk);
}
- for (job = block_job_next(NULL); job; job = block_job_next(job)) {
- block_job_iostatus_reset(job);
+ WITH_JOB_LOCK_GUARD() {
+ for (job = block_job_next_locked(NULL); job;
+ job = block_job_next_locked(job)) {
+ block_job_iostatus_reset_locked(job);
+ }
}
/* Continuing after completed migration. Images have been inactivated to
}
typedef struct StatsCallbacks {
+ StatsProvider provider;
StatRetrieveFunc *stats_cb;
SchemaRetrieveFunc *schemas_cb;
QTAILQ_ENTRY(StatsCallbacks) next;
static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
QTAILQ_HEAD_INITIALIZER(stats_callbacks);
-void add_stats_callbacks(StatRetrieveFunc *stats_fn,
+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;
static bool invoke_stats_cb(StatsCallbacks *entry,
StatsResultList **stats_results,
- StatsFilter *filter,
+ StatsFilter *filter, StatsRequest *request,
Error **errp)
{
+ strList *targets = NULL;
+ strList *names = NULL;
ERRP_GUARD();
- entry->stats_cb(stats_results, filter->target, errp);
+ 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;
+ default:
+ abort();
+ }
+
+ entry->stats_cb(stats_results, filter->target, names, targets, errp);
if (*errp) {
qapi_free_StatsResultList(*stats_results);
*stats_results = NULL;
{
StatsResultList *stats_results = NULL;
StatsCallbacks *entry;
+ StatsRequestList *request;
QTAILQ_FOREACH(entry, &stats_callbacks, next) {
- if (!invoke_stats_cb(entry, &stats_results, filter, errp)) {
- break;
+ 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(Error **errp)
+StatsSchemaList *qmp_query_stats_schemas(bool has_provider,
+ StatsProvider provider,
+ Error **errp)
{
StatsSchemaList *stats_results = NULL;
StatsCallbacks *entry;
ERRP_GUARD();
QTAILQ_FOREACH(entry, &stats_callbacks, next) {
- entry->schemas_cb(&stats_results, errp);
- if (*errp) {
- qapi_free_StatsSchemaList(stats_results);
- return NULL;
+ if (!has_provider || provider == entry->provider) {
+ entry->schemas_cb(&stats_results, errp);
+ if (*errp) {
+ qapi_free_StatsSchemaList(stats_results);
+ return NULL;
+ }
}
}
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;
+}