summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/qapi.c20
-rw-r--r--hmp.c2
-rw-r--r--qapi/block-core.json11
-rw-r--r--qmp-commands.hx2
4 files changed, 25 insertions, 10 deletions
diff --git a/block/qapi.c b/block/qapi.c
index d70336a012..3a14559ca0 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -300,7 +300,8 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
qapi_free_BlockInfo(info);
}
-static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
+static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
+ bool query_backing)
{
BlockStats *s;
@@ -330,12 +331,12 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
if (bs->file) {
s->has_parent = true;
- s->parent = bdrv_query_stats(bs->file);
+ s->parent = bdrv_query_stats(bs->file, query_backing);
}
- if (bs->backing_hd) {
+ if (query_backing && bs->backing_hd) {
s->has_backing = true;
- s->backing = bdrv_query_stats(bs->backing_hd);
+ s->backing = bdrv_query_stats(bs->backing_hd, query_backing);
}
return s;
@@ -366,17 +367,22 @@ BlockInfoList *qmp_query_block(Error **errp)
return NULL;
}
-BlockStatsList *qmp_query_blockstats(Error **errp)
+BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
+ bool query_nodes,
+ Error **errp)
{
BlockStatsList *head = NULL, **p_next = &head;
BlockDriverState *bs = NULL;
- while ((bs = bdrv_next(bs))) {
+ /* Just to be safe if query_nodes is not always initialized */
+ query_nodes = has_query_nodes && query_nodes;
+
+ while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
BlockStatsList *info = g_malloc0(sizeof(*info));
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- info->value = bdrv_query_stats(bs);
+ info->value = bdrv_query_stats(bs, !query_nodes);
aio_context_release(ctx);
*p_next = info;
diff --git a/hmp.c b/hmp.c
index 63d76868b9..94b27df086 100644
--- a/hmp.c
+++ b/hmp.c
@@ -403,7 +403,7 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
{
BlockStatsList *stats_list, *stats;
- stats_list = qmp_query_blockstats(NULL);
+ stats_list = qmp_query_blockstats(false, false, NULL);
for (stats = stats_list; stats; stats = stats->next) {
if (!stats->value->has_device) {
diff --git a/qapi/block-core.json b/qapi/block-core.json
index de1bd45564..8e51e78e1b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -427,11 +427,20 @@
#
# Query the @BlockStats for all virtual block devices.
#
+# @query-nodes: #optional If true, the command will query all the block nodes
+# that have a node name, in a list which will include "parent"
+# information, but not "backing".
+# If false or omitted, the behavior is as before - query all the
+# device backends, recursively including their "parent" and
+# "backing". (Since 2.3)
+#
# Returns: A list of @BlockStats for each virtual block devices.
#
# Since: 0.14.0
##
-{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }
+{ 'command': 'query-blockstats',
+ 'data': { '*query-nodes': 'bool' },
+ 'returns': ['BlockStats'] }
##
# @BlockdevOnError:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 718dd92f6a..d4b00101c7 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2347,7 +2347,7 @@ EQMP
{
.name = "query-blockstats",
- .args_type = "",
+ .args_type = "query-nodes:b?",
.mhandler.cmd_new = qmp_marshal_input_query_blockstats,
},