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
---
blockdev.c | 79
qapi/block-core.json | 32 +
qmp-commands.hx | 67
3 files changed, 178 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 62a4586..df40e92 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2186,6 +2186,23 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
aio_context_release(aio_context);
}
+static void do_child_add(const char *device, QDict *opts, Error **errp)
+{
+BlockDriverState *bs;
+Error *local_err = NULL;
+
+bs = bdrv_lookup_bs(device, device, local_err);
+if (!bs) {
+error_propagate(errp, local_err);
+return;
+}
+
+bdrv_add_child(bs, opts, local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
void qmp_block_resize(bool has_device, const char *device,
bool has_node_name, const char *node_name,
int64_t size, Error **errp)
@@ -3096,6 +3113,68 @@ fail:
qmp_output_visitor_cleanup(ov);
}
+void qmp_child_add(const char *device, BlockdevOptionsChild *options,
+ Error **errp)
+{
+QmpOutputVisitor *ov = qmp_output_visitor_new();
+QObject *obj;
+QDict *qdict;
+Error *local_err = NULL;
+
+if (options-child-has_id || options-child-has_discard ||
+options-child-has_cache || options-child-has_aio ||
+options-child-has_rerror || options-child-has_werror ||
+options-child-has_read_only || options-child-has_detect_zeroes) {
+error_setg(errp, id, discard, cache, aio, rerror, werror, readonly
+and detect_zeroes cann't be used for child-add);
+goto fail;
+}
+
+visit_type_BlockdevOptionsChild(qmp_output_get_visitor(ov),
+options, NULL, local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+goto fail;
+}
+
+obj = qmp_output_get_qobject(ov);
+qdict = qobject_to_qdict(obj);
+
+qdict_flatten(qdict);
+
+do_child_add(device, qdict, local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+goto fail;
+}
+
+fail:
+qmp_output_visitor_cleanup(ov);
+}
+
+void qmp_child_del(const char *parent, const char *child, Error **errp)
+{
+BlockDriverState *parent_bs, *child_bs;
+Error *local_err = NULL;
+
+parent_bs = bdrv_lookup_bs(parent, parent, local_err);
+if (!parent_bs) {
+error_propagate(errp, local_err);
+return;
+}
+
+child_bs = bdrv_lookup_bs(child, child, local_err);
+if (!child_bs) {
+error_propagate(errp, local_err);
+return;
+}
+
+bdrv_del_child(parent_bs, child_bs, local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
{
BlockJobInfoList *head = NULL, **p_next = head;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3ed8114..4d82944 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2122,3 +2122,35 @@
##
{ 'command': 'block-set-write-threshold',
'data': { 'node-name': 'str', 'write-threshold': 'uint64' } }
+
+{
+ 'struct': 'BlockdevOptionsChild',
+ 'data': { 'child': 'BlockdevOptions'} }
+
+##
+# @child-add
+#
+# Add a new child to quorum. This is useful to fix a broken quorum child.
+#
+# @device: graph node name or id which the child will be added to.
+#
+# @options: the options to create child BDS.
+#
+# Since: 2.5
+##
+{ 'command': 'child-add',
+ 'data' : { 'device': 'str', 'options': 'BlockdevOptionsChild' } }
+
+##
+# @child-del
+#
+# Remove a child from quorum. This is useful to fix a broken quorum child.
+#
+# @parent: graph node name or id from which the child will removed.
+#
+# @child: graph node name that will be removed.
+#
+# Since: 2.5
+##
+{ 'command': 'child-del',
+ 'data' : { 'parent': 'str', 'child': 'str' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ba630b1..79a1146 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3872,6 +3872,73 @@ Example (2):
EQMP
{
+.name = child-add,
+.args_type = device:B,options:q,
+.mhandler.cmd_new = qmp_marshal_input_child_add,
+},
+
+SQMP
+child-add
+
+
+Add a child to a quorum node.
+
+This command is still a work in progress. It doesn't support all
+block drivers. Stay away from it unless you want it to help with
+its development.
+
+Arguments:
+
+- device: the quorum's id or node name
+- options: the new child options
+
+Example:
+
+- { execute: child-add,
+arguments: {
+device: disk1,
+options : {
+child: {
+driver: qcow2,
+file: {
+driver: file,
+