stats-qmp-cmds.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * QMP commands related to stats
  3. *
  4. * This work is licensed under the terms of the GNU GPL, version 2 or
  5. * (at your option) any later version.
  6. */
  7. #include "qemu/osdep.h"
  8. #include "system/stats.h"
  9. #include "qapi/qapi-commands-stats.h"
  10. #include "qemu/queue.h"
  11. #include "qapi/error.h"
  12. typedef struct StatsCallbacks {
  13. StatsProvider provider;
  14. StatRetrieveFunc *stats_cb;
  15. SchemaRetrieveFunc *schemas_cb;
  16. QTAILQ_ENTRY(StatsCallbacks) next;
  17. } StatsCallbacks;
  18. static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
  19. QTAILQ_HEAD_INITIALIZER(stats_callbacks);
  20. void add_stats_callbacks(StatsProvider provider,
  21. StatRetrieveFunc *stats_fn,
  22. SchemaRetrieveFunc *schemas_fn)
  23. {
  24. StatsCallbacks *entry = g_new(StatsCallbacks, 1);
  25. entry->provider = provider;
  26. entry->stats_cb = stats_fn;
  27. entry->schemas_cb = schemas_fn;
  28. QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next);
  29. }
  30. static bool invoke_stats_cb(StatsCallbacks *entry,
  31. StatsResultList **stats_results,
  32. StatsFilter *filter, StatsRequest *request,
  33. Error **errp)
  34. {
  35. ERRP_GUARD();
  36. strList *targets = NULL;
  37. strList *names = NULL;
  38. if (request) {
  39. if (request->provider != entry->provider) {
  40. return true;
  41. }
  42. if (request->has_names && !request->names) {
  43. return true;
  44. }
  45. names = request->has_names ? request->names : NULL;
  46. }
  47. switch (filter->target) {
  48. case STATS_TARGET_VM:
  49. break;
  50. case STATS_TARGET_VCPU:
  51. if (filter->u.vcpu.has_vcpus) {
  52. if (!filter->u.vcpu.vcpus) {
  53. /* No targets allowed? Return no statistics. */
  54. return true;
  55. }
  56. targets = filter->u.vcpu.vcpus;
  57. }
  58. break;
  59. case STATS_TARGET_CRYPTODEV:
  60. break;
  61. default:
  62. abort();
  63. }
  64. entry->stats_cb(stats_results, filter->target, names, targets, errp);
  65. if (*errp) {
  66. qapi_free_StatsResultList(*stats_results);
  67. *stats_results = NULL;
  68. return false;
  69. }
  70. return true;
  71. }
  72. StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp)
  73. {
  74. StatsResultList *stats_results = NULL;
  75. StatsCallbacks *entry;
  76. StatsRequestList *request;
  77. QTAILQ_FOREACH(entry, &stats_callbacks, next) {
  78. if (filter->has_providers) {
  79. for (request = filter->providers; request; request = request->next) {
  80. if (!invoke_stats_cb(entry, &stats_results, filter,
  81. request->value, errp)) {
  82. break;
  83. }
  84. }
  85. } else {
  86. if (!invoke_stats_cb(entry, &stats_results, filter, NULL, errp)) {
  87. break;
  88. }
  89. }
  90. }
  91. return stats_results;
  92. }
  93. StatsSchemaList *qmp_query_stats_schemas(bool has_provider,
  94. StatsProvider provider,
  95. Error **errp)
  96. {
  97. ERRP_GUARD();
  98. StatsSchemaList *stats_results = NULL;
  99. StatsCallbacks *entry;
  100. QTAILQ_FOREACH(entry, &stats_callbacks, next) {
  101. if (!has_provider || provider == entry->provider) {
  102. entry->schemas_cb(&stats_results, errp);
  103. if (*errp) {
  104. qapi_free_StatsSchemaList(stats_results);
  105. return NULL;
  106. }
  107. }
  108. }
  109. return stats_results;
  110. }
  111. void add_stats_entry(StatsResultList **stats_results, StatsProvider provider,
  112. const char *qom_path, StatsList *stats_list)
  113. {
  114. StatsResult *entry = g_new0(StatsResult, 1);
  115. entry->provider = provider;
  116. entry->qom_path = g_strdup(qom_path);
  117. entry->stats = stats_list;
  118. QAPI_LIST_PREPEND(*stats_results, entry);
  119. }
  120. void add_stats_schema(StatsSchemaList **schema_results,
  121. StatsProvider provider, StatsTarget target,
  122. StatsSchemaValueList *stats_list)
  123. {
  124. StatsSchema *entry = g_new0(StatsSchema, 1);
  125. entry->provider = provider;
  126. entry->target = target;
  127. entry->stats = stats_list;
  128. QAPI_LIST_PREPEND(*schema_results, entry);
  129. }
  130. bool apply_str_list_filter(const char *string, strList *list)
  131. {
  132. strList *str_list = NULL;
  133. if (!list) {
  134. return true;
  135. }
  136. for (str_list = list; str_list; str_list = str_list->next) {
  137. if (g_str_equal(string, str_list->value)) {
  138. return true;
  139. }
  140. }
  141. return false;
  142. }