From: Wen Congyang <we...@cn.fujitsu.com> In some cases, we want to take a quorum child offline, and take another child online.
Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> Signed-off-by: Gonglei <arei.gong...@huawei.com> Signed-off-by: Changlong Xie <xiecl.f...@cn.fujitsu.com> Reviewed-by: Eric Blake <ebl...@redhat.com> Reviewed-by: Alberto Garcia <be...@igalia.com> --- block.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ include/block/block.h | 5 +++++ include/block/block_int.h | 5 +++++ 3 files changed, 60 insertions(+) diff --git a/block.c b/block.c index 411edbf..a347008 100644 --- a/block.c +++ b/block.c @@ -4320,3 +4320,53 @@ void bdrv_refresh_filename(BlockDriverState *bs) QDECREF(json); } } + +/* + * Hot add/remove a BDS's child. So the user can take a child offline when + * it is broken and take a new child online + */ +void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs, + Error **errp) +{ + + if (!parent_bs->drv || !parent_bs->drv->bdrv_add_child) { + error_setg(errp, "The node %s doesn't support adding a child", + bdrv_get_device_or_node_name(parent_bs)); + return; + } + + if (!QLIST_EMPTY(&child_bs->parents)) { + error_setg(errp, "The node %s already has a parent", + child_bs->node_name); + return; + } + + parent_bs->drv->bdrv_add_child(parent_bs, child_bs, errp); +} + +void bdrv_del_child(BlockDriverState *parent_bs, BlockDriverState *child_bs, + Error **errp) +{ + BdrvChild *child; + + if (!parent_bs->drv || !parent_bs->drv->bdrv_del_child) { + error_setg(errp, "The node %s doesn't support removing a child", + bdrv_get_device_or_node_name(parent_bs)); + return; + } + + QLIST_FOREACH(child, &parent_bs->children, next) { + if (child->bs == child_bs) { + break; + } + } + + if (!child) { + error_setg(errp, "The node %s is not a child of %s", + bdrv_get_device_or_node_name(child_bs), + bdrv_get_device_or_node_name(parent_bs)); + return; + } + + parent_bs->drv->bdrv_del_child(parent_bs, child_bs, errp); +} diff --git a/include/block/block.h b/include/block/block.h index db8e096..863a7c8 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -578,4 +578,9 @@ void bdrv_drained_begin(BlockDriverState *bs); */ void bdrv_drained_end(BlockDriverState *bs); +void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child, + Error **errp); +void bdrv_del_child(BlockDriverState *parent, BlockDriverState *child, + Error **errp); + #endif diff --git a/include/block/block_int.h b/include/block/block_int.h index 256609d..ebe8b1e 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -303,6 +303,11 @@ struct BlockDriver { */ void (*bdrv_drain)(BlockDriverState *bs); + void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child, + Error **errp); + void (*bdrv_del_child)(BlockDriverState *parent, BlockDriverState *child, + Error **errp); + QLIST_ENTRY(BlockDriver) list; }; -- 1.9.3