@@ -193,6 +193,23 @@ actions (drive options rerror, werror).
ETEXI
{
+ .name = "blockdev_change",
+ .args_type = "op:s,parent:B,child:B?,node:?",
+ .params = "operation parent [child] [node]",
+ .help = "Dynamic reconfigure the block driver state graph",
+ .mhandler.cmd = hmp_blockdev_change,
+ },
+
+STEXI
+@item blockdev_change @var{operation} @var{parent} [@var{child}] [@var{node}]
+@findex blockdev_change
+Dynamic reconfigure the block driver state graph. It can be used to
+add, remove, insert, replace a block driver state. Currently only
+the Quorum driver implements this feature to add and remove its child.
+This is useful to fix a broken quorum child.
+ETEXI
+
+ {
.name = "change",
.args_type = "device:B,target:F,arg:s?",
.params = "device filename [format]",
@@ -2346,3 +2346,41 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
qapi_free_RockerOfDpaGroupList(list);
}
+
+void hmp_blockdev_change(Monitor *mon, const QDict *qdict)
+{
+ const char *operation = qdict_get_str(qdict, "op");
+ const char *parent = qdict_get_str(qdict, "parent");
+ const char *child = qdict_get_try_str(qdict, "child");
+ const char *node = qdict_get_try_str(qdict, "node");
+ ChangeOperation op = CHANGE_OPERATION_ADD;
+ Error *local_err = NULL;
+ bool has_child = !!child;
+ bool has_node = !!node;
+
+ while (ChangeOperation_lookup[op] != NULL) {
+ if (strcmp(ChangeOperation_lookup[op], operation) == 0) {
+ break;
+ }
+ op++;
+ }
+
+ if (ChangeOperation_lookup[op] == NULL) {
+ error_setg(&local_err, "Invalid parameter '%s'", "operation");
+ goto out;
+ }
+
+ /*
+ * FIXME: we must specify the parameter child, otherwise,
+ * we can't specify the parameter node.
+ */
+ if (op == CHANGE_OPERATION_ADD) {
+ has_child = false;
+ }
+
+ qmp_x_blockdev_change(op, parent, has_child, child,
+ has_node, node, &local_err);
+
+out:
+ hmp_handle_error(mon, &local_err);
+}
@@ -130,5 +130,6 @@ void hmp_rocker(Monitor *mon, const QDict *qdict);
void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
+void hmp_blockdev_change(Monitor *mon, const QDict *qdict);
#endif