aboutsummaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/blockdev.c b/blockdev.c
index 84dd678289..3cc51b2ee7 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -4287,6 +4287,53 @@ fail:
visit_free(v);
}
+void qmp_x_blockdev_reopen(BlockdevOptions *options, Error **errp)
+{
+ BlockDriverState *bs;
+ AioContext *ctx;
+ QObject *obj;
+ Visitor *v = qobject_output_visitor_new(&obj);
+ Error *local_err = NULL;
+ BlockReopenQueue *queue;
+ QDict *qdict;
+
+ /* Check for the selected node name */
+ if (!options->has_node_name) {
+ error_setg(errp, "Node name not specified");
+ goto fail;
+ }
+
+ bs = bdrv_find_node(options->node_name);
+ if (!bs) {
+ error_setg(errp, "Cannot find node named '%s'", options->node_name);
+ goto fail;
+ }
+
+ /* Put all options in a QDict and flatten it */
+ visit_type_BlockdevOptions(v, NULL, &options, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto fail;
+ }
+
+ visit_complete(v, &obj);
+ qdict = qobject_to(QDict, obj);
+
+ qdict_flatten(qdict);
+
+ /* Perform the reopen operation */
+ ctx = bdrv_get_aio_context(bs);
+ aio_context_acquire(ctx);
+ bdrv_subtree_drained_begin(bs);
+ queue = bdrv_reopen_queue(NULL, bs, qdict, false);
+ bdrv_reopen_multiple(queue, errp);
+ bdrv_subtree_drained_end(bs);
+ aio_context_release(ctx);
+
+fail:
+ visit_free(v);
+}
+
void qmp_blockdev_del(const char *node_name, Error **errp)
{
AioContext *aio_context;