mirror of https://github.com/xemu-project/xemu.git
Add new block driver interface to add/delete a BDS's child
In some cases, we want to take a quorum child offline, and take another child online. Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com> Signed-off-by: Gonglei <arei.gonglei@huawei.com> Signed-off-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Message-id: 1462865799-19402-2-git-send-email-xiecl.fnst@cn.fujitsu.com Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
263a6f4c3a
commit
e06018ad28
49
block.c
49
block.c
|
@ -4011,3 +4011,52 @@ void bdrv_refresh_filename(BlockDriverState *bs)
|
||||||
QDECREF(json);
|
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 does not 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, BdrvChild *child, Error **errp)
|
||||||
|
{
|
||||||
|
BdrvChild *tmp;
|
||||||
|
|
||||||
|
if (!parent_bs->drv || !parent_bs->drv->bdrv_del_child) {
|
||||||
|
error_setg(errp, "The node %s does not support removing a child",
|
||||||
|
bdrv_get_device_or_node_name(parent_bs));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLIST_FOREACH(tmp, &parent_bs->children, next) {
|
||||||
|
if (tmp == child) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmp) {
|
||||||
|
error_setg(errp, "The node %s does not have a child named %s",
|
||||||
|
bdrv_get_device_or_node_name(parent_bs),
|
||||||
|
bdrv_get_device_or_node_name(child->bs));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_bs->drv->bdrv_del_child(parent_bs, child, errp);
|
||||||
|
}
|
||||||
|
|
|
@ -542,4 +542,8 @@ void bdrv_drained_begin(BlockDriverState *bs);
|
||||||
*/
|
*/
|
||||||
void bdrv_drained_end(BlockDriverState *bs);
|
void bdrv_drained_end(BlockDriverState *bs);
|
||||||
|
|
||||||
|
void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
|
||||||
|
Error **errp);
|
||||||
|
void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -314,6 +314,11 @@ struct BlockDriver {
|
||||||
*/
|
*/
|
||||||
void (*bdrv_drain)(BlockDriverState *bs);
|
void (*bdrv_drain)(BlockDriverState *bs);
|
||||||
|
|
||||||
|
void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
|
||||||
|
Error **errp);
|
||||||
|
void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
QLIST_ENTRY(BlockDriver) list;
|
QLIST_ENTRY(BlockDriver) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue