#include "block/block_int.h"
#include "block/throttle-groups.h"
#include "block/write-threshold.h"
-#include "qmp-commands.h"
-#include "qapi-visit.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-block-core.h"
#include "qapi/qobject-output-visitor.h"
+#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "sysemu/block-backend.h"
qapi_free_BlockInfo(info);
}
+static uint64List *uint64_list(uint64_t *list, int size)
+{
+ int i;
+ uint64List *out_list = NULL;
+ uint64List **pout_list = &out_list;
+
+ for (i = 0; i < size; i++) {
+ uint64List *entry = g_new(uint64List, 1);
+ entry->value = list[i];
+ *pout_list = entry;
+ pout_list = &entry->next;
+ }
+
+ *pout_list = NULL;
+
+ return out_list;
+}
+
+static void bdrv_latency_histogram_stats(BlockLatencyHistogram *hist,
+ bool *not_null,
+ BlockLatencyHistogramInfo **info)
+{
+ *not_null = hist->bins != NULL;
+ if (*not_null) {
+ *info = g_new0(BlockLatencyHistogramInfo, 1);
+
+ (*info)->boundaries = uint64_list(hist->boundaries, hist->nbins - 1);
+ (*info)->bins = uint64_list(hist->bins, hist->nbins);
+ }
+}
+
static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
{
BlockAcctStats *stats = blk_get_stats(blk);
dev_stats->avg_wr_queue_depth =
block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);
}
+
+ bdrv_latency_histogram_stats(&stats->latency_histogram[BLOCK_ACCT_READ],
+ &ds->has_x_rd_latency_histogram,
+ &ds->x_rd_latency_histogram);
+ bdrv_latency_histogram_stats(&stats->latency_histogram[BLOCK_ACCT_WRITE],
+ &ds->has_x_wr_latency_histogram,
+ &ds->x_wr_latency_histogram);
+ bdrv_latency_histogram_stats(&stats->latency_histogram[BLOCK_ACCT_FLUSH],
+ &ds->has_x_flush_latency_histogram,
+ &ds->x_flush_latency_histogram);
}
static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
p_next = &info->next;
}
} else {
- for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
- BlockStatsList *info = g_malloc0(sizeof(*info));
+ for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
+ BlockStatsList *info;
AioContext *ctx = blk_get_aio_context(blk);
BlockStats *s;
+ char *qdev;
+
+ if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
+ continue;
+ }
aio_context_acquire(ctx);
s = bdrv_query_bds_stats(blk_bs(blk), true);
s->has_device = true;
s->device = g_strdup(blk_name(blk));
+
+ qdev = blk_get_attached_dev_id(blk);
+ if (qdev && *qdev) {
+ s->has_qdev = true;
+ s->qdev = qdev;
+ } else {
+ g_free(qdev);
+ }
+
bdrv_query_blk_stats(s->stats, blk);
aio_context_release(ctx);
+ info = g_malloc0(sizeof(*info));
info->value = s;
*p_next = info;
p_next = &info->next;
{
switch (qobject_type(obj)) {
case QTYPE_QNUM: {
- QNum *value = qobject_to_qnum(obj);
+ QNum *value = qobject_to(QNum, obj);
char *tmp = qnum_to_string(value);
func_fprintf(f, "%s", tmp);
g_free(tmp);
break;
}
case QTYPE_QSTRING: {
- QString *value = qobject_to_qstring(obj);
+ QString *value = qobject_to(QString, obj);
func_fprintf(f, "%s", qstring_get_str(value));
break;
}
case QTYPE_QDICT: {
- QDict *value = qobject_to_qdict(obj);
+ QDict *value = qobject_to(QDict, obj);
dump_qdict(func_fprintf, f, comp_indent, value);
break;
}
case QTYPE_QLIST: {
- QList *value = qobject_to_qlist(obj);
+ QList *value = qobject_to(QList, obj);
dump_qlist(func_fprintf, f, comp_indent, value);
break;
}
case QTYPE_QBOOL: {
- QBool *value = qobject_to_qbool(obj);
+ QBool *value = qobject_to(QBool, obj);
func_fprintf(f, "%s", qbool_get_bool(value) ? "true" : "false");
break;
}
visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
visit_complete(v, &obj);
- data = qdict_get(qobject_to_qdict(obj), "data");
+ data = qdict_get(qobject_to(QDict, obj), "data");
dump_qobject(func_fprintf, f, 1, data);
- qobject_decref(obj);
+ qobject_unref(obj);
visit_free(v);
}