* [PATCH RFC v2 0/4] blockdev-replace
@ 2021-12-22 16:02 Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 1/4] block-backend: blk_root(): drop const specifier on return type Vladimir Sementsov-Ogievskiy
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2021-12-22 16:02 UTC (permalink / raw)
To: qemu-block
Cc: qemu-devel, eblake, armbru, hreitz, kwolf, vsementsov, den,
nshirokovskiy, yur, dim, igor, pkrempa, libvir-list, stefanha
Hi all!
v2:
1. Let's start with minimal functionality: replace only one specific
child.
2. Explicit type of parent: qdev / export / driver
Hmm, 'driver' is for BlockDriverState.. Any better idea? I don't want to
call it "node" or even "block-node", as finally, devices and exports are
kind of nodes too in the whole block graph..
3. I think it's better to start with x- prefix
Plans for v3:
- add tests of filter insertion and removing
- add qmp transaction support
Vladimir Sementsov-Ogievskiy (4):
block-backend: blk_root(): drop const specifier on return type
block/export: add blk_by_export_id()
block: make bdrv_find_child() function public
qapi: add blockdev-replace command
qapi/block.json | 61 ++++++++++++++++++++++++++++++++++
include/block/block_int.h | 1 +
include/sysemu/block-backend.h | 3 +-
block.c | 13 ++++++++
block/block-backend.c | 2 +-
block/export/export.c | 18 ++++++++++
block/qapi-sysemu.c | 56 +++++++++++++++++++++++++++++++
blockdev.c | 14 --------
8 files changed, 152 insertions(+), 16 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/4] block-backend: blk_root(): drop const specifier on return type
2021-12-22 16:02 [PATCH RFC v2 0/4] blockdev-replace Vladimir Sementsov-Ogievskiy
@ 2021-12-22 16:02 ` Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 2/4] block/export: add blk_by_export_id() Vladimir Sementsov-Ogievskiy
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2021-12-22 16:02 UTC (permalink / raw)
To: qemu-block
Cc: qemu-devel, eblake, armbru, hreitz, kwolf, vsementsov, den,
nshirokovskiy, yur, dim, igor, pkrempa, libvir-list, stefanha
We'll need get non-const child pointer for graph modifications in
further commits.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
include/sysemu/block-backend.h | 2 +-
block/block-backend.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index e5e1524f06..904d70f49c 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -277,7 +277,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags);
-const BdrvChild *blk_root(BlockBackend *blk);
+BdrvChild *blk_root(BlockBackend *blk);
int blk_make_empty(BlockBackend *blk, Error **errp);
diff --git a/block/block-backend.c b/block/block-backend.c
index 12ef80ea17..d994a0f096 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -2438,7 +2438,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
bytes, read_flags, write_flags);
}
-const BdrvChild *blk_root(BlockBackend *blk)
+BdrvChild *blk_root(BlockBackend *blk)
{
return blk->root;
}
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/4] block/export: add blk_by_export_id()
2021-12-22 16:02 [PATCH RFC v2 0/4] blockdev-replace Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 1/4] block-backend: blk_root(): drop const specifier on return type Vladimir Sementsov-Ogievskiy
@ 2021-12-22 16:02 ` Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 3/4] block: make bdrv_find_child() function public Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 4/4] qapi: add blockdev-replace command Vladimir Sementsov-Ogievskiy
3 siblings, 0 replies; 5+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2021-12-22 16:02 UTC (permalink / raw)
To: qemu-block
Cc: qemu-devel, eblake, armbru, hreitz, kwolf, vsementsov, den,
nshirokovskiy, yur, dim, igor, pkrempa, libvir-list, stefanha
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
include/sysemu/block-backend.h | 1 +
block/export/export.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 904d70f49c..250c7465a5 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -124,6 +124,7 @@ DeviceState *blk_get_attached_dev(BlockBackend *blk);
char *blk_get_attached_dev_id(BlockBackend *blk);
BlockBackend *blk_by_dev(void *dev);
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
+BlockBackend *blk_by_export_id(const char *id, Error **errp);
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
diff --git a/block/export/export.c b/block/export/export.c
index 6d3b9964c8..613b5bc1d5 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -362,3 +362,21 @@ BlockExportInfoList *qmp_query_block_exports(Error **errp)
return head;
}
+
+BlockBackend *blk_by_export_id(const char *id, Error **errp)
+{
+ BlockExport *exp;
+
+ exp = blk_exp_find(id);
+ if (exp == NULL) {
+ error_setg(errp, "Export '%s' not found", id);
+ return NULL;
+ }
+
+ if (!exp->blk) {
+ error_setg(errp, "Export '%s' is empty", id);
+ return NULL;
+ }
+
+ return exp->blk;
+}
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/4] block: make bdrv_find_child() function public
2021-12-22 16:02 [PATCH RFC v2 0/4] blockdev-replace Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 1/4] block-backend: blk_root(): drop const specifier on return type Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 2/4] block/export: add blk_by_export_id() Vladimir Sementsov-Ogievskiy
@ 2021-12-22 16:02 ` Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 4/4] qapi: add blockdev-replace command Vladimir Sementsov-Ogievskiy
3 siblings, 0 replies; 5+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2021-12-22 16:02 UTC (permalink / raw)
To: qemu-block
Cc: qemu-devel, eblake, armbru, hreitz, kwolf, vsementsov, den,
nshirokovskiy, yur, dim, igor, pkrempa, libvir-list, stefanha
To be reused soon.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
include/block/block_int.h | 1 +
block.c | 13 +++++++++++++
blockdev.c | 14 --------------
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/include/block/block_int.h b/include/block/block_int.h
index f4c75e8ba9..79bdde8bf4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1433,6 +1433,7 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
BlockDriverState **bitmap_bs,
Error **errp);
+BdrvChild *bdrv_find_child(BlockDriverState *parent_bs, const char *child_name);
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
BdrvChild *bdrv_filter_child(BlockDriverState *bs);
BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs);
diff --git a/block.c b/block.c
index 0ac5b163d2..840d52e7c8 100644
--- a/block.c
+++ b/block.c
@@ -7727,6 +7727,19 @@ int bdrv_make_empty(BdrvChild *c, Error **errp)
return 0;
}
+BdrvChild *bdrv_find_child(BlockDriverState *parent_bs, const char *child_name)
+{
+ BdrvChild *child;
+
+ QLIST_FOREACH(child, &parent_bs->children, next) {
+ if (strcmp(child->name, child_name) == 0) {
+ return child;
+ }
+ }
+
+ return NULL;
+}
+
/*
* Return the child that @bs acts as an overlay for, and from which data may be
* copied in COW or COR operations. Usually this is the backing file.
diff --git a/blockdev.c b/blockdev.c
index 0eb2823b1b..ce23059d5e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3644,20 +3644,6 @@ out:
aio_context_release(aio_context);
}
-static BdrvChild *bdrv_find_child(BlockDriverState *parent_bs,
- const char *child_name)
-{
- BdrvChild *child;
-
- QLIST_FOREACH(child, &parent_bs->children, next) {
- if (strcmp(child->name, child_name) == 0) {
- return child;
- }
- }
-
- return NULL;
-}
-
void qmp_x_blockdev_change(const char *parent, bool has_child,
const char *child, bool has_node,
const char *node, Error **errp)
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 4/4] qapi: add blockdev-replace command
2021-12-22 16:02 [PATCH RFC v2 0/4] blockdev-replace Vladimir Sementsov-Ogievskiy
` (2 preceding siblings ...)
2021-12-22 16:02 ` [PATCH v2 3/4] block: make bdrv_find_child() function public Vladimir Sementsov-Ogievskiy
@ 2021-12-22 16:02 ` Vladimir Sementsov-Ogievskiy
3 siblings, 0 replies; 5+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2021-12-22 16:02 UTC (permalink / raw)
To: qemu-block
Cc: qemu-devel, eblake, armbru, hreitz, kwolf, vsementsov, den,
nshirokovskiy, yur, dim, igor, pkrempa, libvir-list, stefanha
Add a command that can replace bs in following BdrvChild structures:
- qdev blk root child
- block-export blk root child
- any child BlockDriverState selected by child-name
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
qapi/block.json | 61 +++++++++++++++++++++++++++++++++++++++++++++
block/qapi-sysemu.c | 56 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+)
diff --git a/qapi/block.json b/qapi/block.json
index 82fcf2c914..a4dd1e34d4 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -570,3 +570,64 @@
'*boundaries-read': ['uint64'],
'*boundaries-write': ['uint64'],
'*boundaries-flush': ['uint64'] } }
+##
+# @BlockParentType:
+#
+# Since 7.0
+##
+{ 'enum': 'BlockParentType',
+ 'data': ['qdev', 'driver', 'export'] }
+
+##
+# @BdrvChildRefQdev:
+#
+# Since 7.0
+##
+{ 'struct': 'BdrvChildRefQdev',
+ 'data': { 'qdev-id': 'str' } }
+
+##
+# @BdrvChildRefExport:
+#
+# Since 7.0
+##
+{ 'struct': 'BdrvChildRefExport',
+ 'data': { 'export-id': 'str' } }
+
+##
+# @BdrvChildRefDriver:
+#
+# Since 7.0
+##
+{ 'struct': 'BdrvChildRefDriver',
+ 'data': { 'node-name': 'str', 'child': 'str' } }
+
+##
+# @BlockdevReplace:
+#
+# Since 7.0
+##
+{ 'union': 'BlockdevReplace',
+ 'base': {
+ 'parent-type': 'BlockParentType',
+ 'new-child': 'str'
+ },
+ 'discriminator': 'parent-type',
+ 'data': {
+ 'qdev': 'BdrvChildRefQdev',
+ 'export': 'BdrvChildRefExport',
+ 'driver': 'BdrvChildRefDriver'
+ } }
+
+##
+# @x-blockdev-replace:
+#
+# Replace a block-node associated with device (selected by
+# @qdev-id) or with block-export (selected by @export-id) or
+# any child of block-node (selected by @node-name and @child)
+# with @new-child block-node.
+#
+# Since 7.0
+##
+{ 'command': 'x-blockdev-replace', 'boxed': true,
+ 'data': 'BlockdevReplace' }
diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c
index 8498402ad4..ca1aaef376 100644
--- a/block/qapi-sysemu.c
+++ b/block/qapi-sysemu.c
@@ -588,3 +588,59 @@ void qmp_block_latency_histogram_set(
}
}
}
+
+void qmp_x_blockdev_replace(BlockdevReplace *repl, Error **errp)
+{
+ BdrvChild *child = NULL;
+ BlockDriverState *new_child_bs;
+
+ if (repl->parent_type == BLOCK_PARENT_TYPE_DRIVER) {
+ BlockDriverState *parent_bs;
+
+ parent_bs = bdrv_find_node(repl->u.driver.node_name);
+ if (!parent_bs) {
+ error_setg(errp, "Block driver node with node-name '%s' not "
+ "found", repl->u.driver.node_name);
+ return;
+ }
+
+ child = bdrv_find_child(parent_bs, repl->u.driver.child);
+ if (!child) {
+ error_setg(errp, "Block driver node '%s' doesn't have child "
+ "named '%s'", repl->u.driver.node_name,
+ repl->u.driver.child);
+ return;
+ }
+ } else {
+ /* Other types are similar, they work through blk */
+ BlockBackend *blk;
+ bool is_qdev = repl->parent_type == BLOCK_PARENT_TYPE_QDEV;
+ const char *id =
+ is_qdev ? repl->u.qdev.qdev_id : repl->u.export.export_id;
+
+ assert(is_qdev || repl->parent_type == BLOCK_PARENT_TYPE_EXPORT);
+
+ blk = is_qdev ? blk_by_qdev_id(id, errp) : blk_by_export_id(id, errp);
+ if (!blk) {
+ return;
+ }
+
+ child = blk_root(blk);
+ if (!child) {
+ error_setg(errp, "%s '%s' is empty, nothing to replace",
+ is_qdev ? "Device" : "Export", id);
+ return;
+ }
+ }
+
+ assert(child);
+ assert(child->bs);
+
+ new_child_bs = bdrv_find_node(repl->new_child);
+ if (!new_child_bs) {
+ error_setg(errp, "Node '%s' not found", repl->new_child);
+ return;
+ }
+
+ bdrv_replace_child_bs(child, new_child_bs, errp);
+}
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-12-22 16:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-22 16:02 [PATCH RFC v2 0/4] blockdev-replace Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 1/4] block-backend: blk_root(): drop const specifier on return type Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 2/4] block/export: add blk_by_export_id() Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 3/4] block: make bdrv_find_child() function public Vladimir Sementsov-Ogievskiy
2021-12-22 16:02 ` [PATCH v2 4/4] qapi: add blockdev-replace command Vladimir Sementsov-Ogievskiy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.