aboutsummaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'block.c')
-rw-r--r--block.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/block.c b/block.c
index 724b3b2db5..0726dab8d0 100644
--- a/block.c
+++ b/block.c
@@ -4011,3 +4011,52 @@ 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 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);
+}