mirror of
https://github.com/mii443/qemu.git
synced 2025-08-22 15:15:46 +00:00
block: Add an 'x-blockdev-reopen' QMP command
This command allows reopening an arbitrary BlockDriverState with a new set of options. Some options (e.g node-name) cannot be changed and some block drivers don't allow reopening, but otherwise this command is modelled after 'blockdev-add' and the state of the reopened BlockDriverState should generally be the same as if it had just been added by 'blockdev-add' with the same set of options. One notable exception is the 'backing' option: 'x-blockdev-reopen' requires that it is always present unless the BlockDriverState in question doesn't have a current or default backing file. This command allows reconfiguring the graph by using the appropriate options to change the children of a node. At the moment it's possible to change a backing file by setting the 'backing' option to the name of the new node, but it should also be possible to add a similar functionality to other block drivers (e.g. Quorum, blkverify). Although the API is unlikely to change, this command is marked experimental for the time being so there's room to see if the semantics need changes. Signed-off-by: Alberto Garcia <berto@igalia.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
committed by
Kevin Wolf
parent
5019aece2a
commit
1479c730c7
47
blockdev.c
47
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;
|
||||
|
Reference in New Issue
Block a user