aboutsummaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/blockdev.c b/blockdev.c
index 0acbace8fd..5ad0e9070e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3559,51 +3559,60 @@ 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);
- BlockReopenQueue *queue;
- QDict *qdict;
+void qmp_x_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
+{
+ BlockReopenQueue *queue = NULL;
+ GSList *drained = NULL;
+
+ /* Add each one of the BDS that we want to reopen to the queue */
+ for (; reopen_list != NULL; reopen_list = reopen_list->next) {
+ BlockdevOptions *options = reopen_list->value;
+ BlockDriverState *bs;
+ AioContext *ctx;
+ QObject *obj;
+ Visitor *v;
+ QDict *qdict;
+
+ /* Check for the selected node name */
+ if (!options->has_node_name) {
+ error_setg(errp, "node-name not specified");
+ goto fail;
+ }
- /* 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, "Failed to find node with node-name='%s'",
+ options->node_name);
+ goto fail;
+ }
- bs = bdrv_find_node(options->node_name);
- if (!bs) {
- error_setg(errp, "Failed to find node with node-name='%s'",
- options->node_name);
- goto fail;
- }
+ /* Put all options in a QDict and flatten it */
+ v = qobject_output_visitor_new(&obj);
+ visit_type_BlockdevOptions(v, NULL, &options, &error_abort);
+ visit_complete(v, &obj);
+ visit_free(v);
- /* Put all options in a QDict and flatten it */
- visit_type_BlockdevOptions(v, NULL, &options, &error_abort);
- visit_complete(v, &obj);
- qdict = qobject_to(QDict, obj);
+ qdict = qobject_to(QDict, obj);
- qdict_flatten(qdict);
+ qdict_flatten(qdict);
- /* Perform the reopen operation */
- ctx = bdrv_get_aio_context(bs);
- aio_context_acquire(ctx);
- bdrv_subtree_drained_begin(bs);
- aio_context_release(ctx);
+ ctx = bdrv_get_aio_context(bs);
+ aio_context_acquire(ctx);
- queue = bdrv_reopen_queue(NULL, bs, qdict, false);
- bdrv_reopen_multiple(queue, errp);
+ bdrv_subtree_drained_begin(bs);
+ queue = bdrv_reopen_queue(queue, bs, qdict, false);
+ drained = g_slist_prepend(drained, bs);
- ctx = bdrv_get_aio_context(bs);
- aio_context_acquire(ctx);
- bdrv_subtree_drained_end(bs);
- aio_context_release(ctx);
+ aio_context_release(ctx);
+ }
+
+ /* Perform the reopen operation */
+ bdrv_reopen_multiple(queue, errp);
+ queue = NULL;
fail:
- visit_free(v);
+ bdrv_reopen_queue_free(queue);
+ g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end);
}
void qmp_blockdev_del(const char *node_name, Error **errp)