[PATCH 8/8] qapi: add blockdev-replace command

Vladimir Sementsov-Ogievskiy vsementsov at virtuozzo.com
Mon Sep 20 11:25:40 UTC 2021


02.08.2021 21:54, Vladimir Sementsov-Ogievskiy wrote:
> Add command that can add and remove filters.
> 
> Key points of functionality:
> 
> What the command does is simply replace some BdrvChild.bs by some other
> nodes. The tricky thing is selecting there BdrvChild objects.
> To be able to select any kind of BdrvChild we use a generic parent_id,
> which may be a node-name, or qdev id or block export id. In future we
> may support block jobs.
> 
> Any kind of ambiguity leads to error. If we have both device named
> device0 and block export named device0 and they both point to same BDS,
> user can't replace root child of one of these parents. So, to be able
> to do replacements, user should avoid duplicating names in different
> parent namespaces.
> 
> So, command allows to replace any single child in the graph.
> 
> On the other hand we want to realize a kind of bdrv_replace_node(),
> which works well when we want to replace all parents of some node. For
> this kind of task @parents-mode argument implemented.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
> ---
>   qapi/block-core.json | 78 +++++++++++++++++++++++++++++++++++++++++
>   block.c              | 82 ++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 160 insertions(+)
> 
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 675d8265eb..8059b96341 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -5433,3 +5433,81 @@
>   { 'command': 'blockdev-snapshot-delete-internal-sync',
>     'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
>     'returns': 'SnapshotInfo' }
> +
> +##
> +# @BlockdevReplaceParentsMode:
> +#
> +# Alternative (to directly set @parent) way to chose parents in
> +# @blockdev-replace
> +#
> +# @exactly-one: Exactly one parent should match a condition, otherwise
> +#               @blockdev-replace fails.
> +#
> +# @all: All matching parents are taken into account. If replacing lead
> +#       to loops in block graph, @blockdev-replace fails.
> +#
> +# @auto: Same as @all, but automatically skip replacing parents if it
> +#        leads to loops in block graph.
> +#
> +# Since: 6.2
> +##
> +{ 'enum': 'BlockdevReplaceParentsMode',
> +  'data': ['exactly-one', 'all', 'auto'] }
> +
> +##
> +# @BlockdevReplace:
> +#
> +# Declaration of one replacement.
> +#
> +# @parent: id of parent. It may be qdev or block export or simple
> +#          node-name. If id is ambiguous (for example node-name of
> +#          some BDS equals to block export name), blockdev-replace
> +#          fails. If not specified, blockdev-replace goes through
> +#          @parents-mode scenario, see below. Note, that @parent and
> +#          @parents-mode can't be specified simultaneously.
> +#          If @parent is specified, only one edge is selected. If
> +#          several edges match the condition, blockdev-replace fails.
> +#
> +# @edge: name of the child. If omitted, any child name matches.
> +#
> +# @child: node-name of the child. If omitted, any child matches.
> +#         Must be present if @parent is not specified.
> +#
> +# @parents-mode: declares how to select edge (or edges) when @parent
> +#                is omitted. Default is 'one'.
> +#
> +# Since: 6.2
> +#
> +# Examples:
> +#
> +# 1. Change root node of some device.
> +#
> +# Note, that @edge name is omitted, as
> +# devices always has only one child. As well, no need in specifying
> +# old @child.
> +#
> +# -> { "parent": "device0", "new-child": "some-node-name" }
> +#
> +# 2. Insert copy-before-write filter.
> +#
> +# Assume, after blockdev-add we have block-node 'source', with several
> +# writing parents and one copy-before-write 'filter' parent. And we want
> +# to actually insert the filter. We do:
> +#
> +# -> { "child": "source", "parent-mode": "auto", "new-child": "filter" }
> +#
> +# All parents of source would be switched to 'filter' node, except for
> +# 'filter' node itself (otherwise, it will make a loop in block-graph).
> +##
> +{ 'struct': 'BlockdevReplace',
> +  'data': { '*parent': 'str', '*edge': 'str', '*child': 'str',
> +            '*parents-mode': 'BlockdevReplaceParentsMode',
> +            'new-child': 'str' } }


We also can make 'new-child' a 'BlockdevRef' and allow creating and inserting the filter in one command.


-- 
Best regards,
Vladimir




More information about the libvir-list mailing list