From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40755) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajAbS-0008Tt-Kt for qemu-devel@nongnu.org; Thu, 24 Mar 2016 15:07:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ajAbR-0004FM-D8 for qemu-devel@nongnu.org; Thu, 24 Mar 2016 15:07:30 -0400 From: Max Reitz Date: Thu, 24 Mar 2016 20:07:18 +0100 Message-Id: <1458846438-28573-2-git-send-email-mreitz@redhat.com> In-Reply-To: <1458846438-28573-1-git-send-email-mreitz@redhat.com> References: <1458846438-28573-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [RFC for-2.7 1/1] block/qapi: Add query-block-node-tree List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: Kevin Wolf , Markus Armbruster , qemu-devel@nongnu.org, Max Reitz This command returns the tree of BlockDriverStates under a given root node. Every tree node is described by its node name and the connection of a parent node to its children additionally contains the role the child assumes. A node's name can then be used e.g. in conjunction with query-named-block-nodes to get more information about the node. Signed-off-by: Max Reitz --- block/qapi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ qapi/block-core.json | 46 ++++++++++++++++++++++++++++++++++++++++++++++ qmp-commands.hx | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/block/qapi.c b/block/qapi.c index 6a4869a..a35d32b 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -493,6 +493,49 @@ BlockInfoList *qmp_query_block(Error **errp) return head; } +static BlockNodeTreeNode *qmp_query_block_node_tree_by_bs(BlockDriverState *bs) +{ + BlockNodeTreeNode *bntn; + BlockNodeTreeChildList **p_next; + BdrvChild *child; + + bntn = g_new0(BlockNodeTreeNode, 1); + + bntn->node_name = g_strdup(bdrv_get_node_name(bs)); + bntn->has_node_name = bntn->node_name; + + p_next = &bntn->children; + QLIST_FOREACH(child, &bs->children, next) { + BlockNodeTreeChild *bntc; + + bntc = g_new(BlockNodeTreeChild, 1); + *bntc = (BlockNodeTreeChild){ + .role = g_strdup(child->name), + .node = qmp_query_block_node_tree_by_bs(child->bs), + }; + + *p_next = g_new0(BlockNodeTreeChildList, 1); + (*p_next)->value = bntc; + p_next = &(*p_next)->next; + } + + *p_next = NULL; + return bntn; +} + +BlockNodeTreeNode *qmp_query_block_node_tree(const char *root_node, + Error **errp) +{ + BlockDriverState *bs; + + bs = bdrv_lookup_bs(root_node, root_node, errp); + if (!bs) { + return NULL; + } + + return qmp_query_block_node_tree_by_bs(bs); +} + static bool next_query_bds(BlockBackend **blk, BlockDriverState **bs, bool query_nodes) { diff --git a/qapi/block-core.json b/qapi/block-core.json index b1cf77d..754ccd6 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -470,6 +470,52 @@ ## +# @BlockNodeTreeNode: +# +# Describes a node in the block node graph. +# +# @node-name: If present, the node's name. +# +# @children: List of the node's children. +# +# Since: 2.7 +## +{ 'struct': 'BlockNodeTreeNode', + 'data': { '*node-name': 'str', + 'children': ['BlockNodeTreeChild'] } } + +## +# @BlockNodeTreeChild: +# +# Describes a child node in the block node graph. +# +# @role: Role the child assumes for its parent, e.g. "file" or "backing". +# +# @node: The child node's BlockNodeTreeNode structure. +# +# Since: 2.7 +## +{ 'struct': 'BlockNodeTreeChild', + 'data': { 'role': 'str', + 'node': 'BlockNodeTreeNode' } } + +## +# @query-block-node-tree: +# +# Queries the tree of nodes under a given node in the block graph. +# +# @root-node: Node name or device name of the tree's root node. +# +# Returns: The root node's BlockNodeTreeNode structure. +# +# Since: 2.7 +## +{ 'command': 'query-block-node-tree', + 'data': { 'root-node': 'str' }, + 'returns': 'BlockNodeTreeNode' } + + +## # @BlockDeviceTimedStats: # # Statistics of a block device during a given interval of time. diff --git a/qmp-commands.hx b/qmp-commands.hx index 9e05365..5c404aa 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2637,6 +2637,44 @@ EQMP }, SQMP +query-block-node-tree +--------------------- + +Queries the tree of nodes under a given node in the block graph. + +Arguments: + +- "root-node": Node name or device name of the tree's root node (json-string) + +The block node tree is represented with BlockNodeTreeNode and BlockNodeTreeChild +json-objects. + +Each BlockNodeTreeNode json-object contains the following: + +- "node-name": If present, the node's name (json-string, optional) +- "children": json-array of the node's children, each entry is a json-object of + type BlockNodeTreeChild + +Each BlockNodeTreeChild json-object contains the following: + +- "role": Role the child node assumes for its parent, e.g. "file" or "backing" + (json-string) +- "node": BlockNodeTreeNode describing the child node (json-object) + +The cyclic reference of BlockNodeTreeNode and BlockNodeTreeChild to each other +thus spawns a tree. + +This command returns the root node's BlockNodeTreeNode structure. + +EQMP + + { + .name = "query-block-node-tree", + .args_type = "root-node:B", + .mhandler.cmd_new = qmp_marshal_query_block_node_tree, + }, + +SQMP query-blockstats ---------------- -- 2.7.4