block: Add 'x-blockdev-del' QMP command
This command is still experimental, hence the name. This is the companion to 'blockdev-add'. It allows deleting a BlockBackend with its associated BlockDriverState tree, or a BlockDriverState that is not attached to any backend. In either case, the command fails if the reference count is greater than 1 or the BlockDriverState has any parents. Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Message-id: 6cfc148c77aca1da942b094d811bfa3fcf7ac7bb.1446475331.git.berto@igalia.com Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
f636ae85f3
commit
81b936ae70
66
blockdev.c
66
blockdev.c
@ -3479,6 +3479,72 @@ fail:
|
||||
qmp_output_visitor_cleanup(ov);
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_del(bool has_id, const char *id,
|
||||
bool has_node_name, const char *node_name, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
|
||||
if (has_id && has_node_name) {
|
||||
error_setg(errp, "Only one of id and node-name must be specified");
|
||||
return;
|
||||
} else if (!has_id && !has_node_name) {
|
||||
error_setg(errp, "No block device specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_id) {
|
||||
blk = blk_by_name(id);
|
||||
if (!blk) {
|
||||
error_setg(errp, "Cannot find block backend %s", id);
|
||||
return;
|
||||
}
|
||||
if (blk_get_refcnt(blk) > 1) {
|
||||
error_setg(errp, "Block backend %s is in use", id);
|
||||
return;
|
||||
}
|
||||
bs = blk_bs(blk);
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
} else {
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Cannot find node %s", node_name);
|
||||
return;
|
||||
}
|
||||
blk = bs->blk;
|
||||
if (blk) {
|
||||
error_setg(errp, "Node %s is in use by %s",
|
||||
node_name, blk_name(blk));
|
||||
return;
|
||||
}
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
}
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (bs) {
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bs->refcnt > 1 || !QLIST_EMPTY(&bs->parents)) {
|
||||
error_setg(errp, "Block device %s is in use",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (blk) {
|
||||
blk_unref(blk);
|
||||
} else {
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
|
||||
{
|
||||
BlockJobInfoList *head = NULL, **p_next = &head;
|
||||
|
@ -1895,8 +1895,8 @@
|
||||
# level and no BlockBackend will be created.
|
||||
#
|
||||
# This command is still a work in progress. It doesn't support all
|
||||
# block drivers, it lacks a matching blockdev-del, and more. Stay
|
||||
# away from it unless you want to help with its development.
|
||||
# block drivers among other things. Stay away from it unless you want
|
||||
# to help with its development.
|
||||
#
|
||||
# @options: block device options for the new device
|
||||
#
|
||||
@ -1904,6 +1904,34 @@
|
||||
##
|
||||
{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
|
||||
|
||||
##
|
||||
# @x-blockdev-del:
|
||||
#
|
||||
# Deletes a block device that has been added using blockdev-add.
|
||||
# The selected device can be either a block backend or a graph node.
|
||||
#
|
||||
# In the former case the backend will be destroyed, along with its
|
||||
# inserted medium if there's any. The command will fail if the backend
|
||||
# or its medium are in use.
|
||||
#
|
||||
# In the latter case the node will be destroyed. The command will fail
|
||||
# if the node is attached to a block backend or is otherwise being
|
||||
# used.
|
||||
#
|
||||
# One of @id or @node-name must be specified, but not both.
|
||||
#
|
||||
# This command is still a work in progress and is considered
|
||||
# experimental. Stay away from it unless you want to help with its
|
||||
# development.
|
||||
#
|
||||
# @id: #optional Name of the block backend device to delete.
|
||||
#
|
||||
# @node-name: #optional Name of the graph node to delete.
|
||||
#
|
||||
# Since: 2.5
|
||||
##
|
||||
{ 'command': 'x-blockdev-del', 'data': { '*id': 'str', '*node-name': 'str' } }
|
||||
|
||||
##
|
||||
# @blockdev-open-tray:
|
||||
#
|
||||
|
@ -3946,8 +3946,8 @@ blockdev-add
|
||||
Add a block device.
|
||||
|
||||
This command is still a work in progress. It doesn't support all
|
||||
block drivers, it lacks a matching blockdev-del, and more. Stay away
|
||||
from it unless you want to help with its development.
|
||||
block drivers among other things. Stay away from it unless you want
|
||||
to help with its development.
|
||||
|
||||
Arguments:
|
||||
|
||||
@ -3990,6 +3990,63 @@ Example (2):
|
||||
|
||||
<- { "return": {} }
|
||||
|
||||
EQMP
|
||||
|
||||
{
|
||||
.name = "x-blockdev-del",
|
||||
.args_type = "id:s?,node-name:s?",
|
||||
.mhandler.cmd_new = qmp_marshal_x_blockdev_del,
|
||||
},
|
||||
|
||||
SQMP
|
||||
x-blockdev-del
|
||||
------------
|
||||
Since 2.5
|
||||
|
||||
Deletes a block device thas has been added using blockdev-add.
|
||||
The selected device can be either a block backend or a graph node.
|
||||
|
||||
In the former case the backend will be destroyed, along with its
|
||||
inserted medium if there's any. The command will fail if the backend
|
||||
or its medium are in use.
|
||||
|
||||
In the latter case the node will be destroyed. The command will fail
|
||||
if the node is attached to a block backend or is otherwise being
|
||||
used.
|
||||
|
||||
One of "id" or "node-name" must be specified, but not both.
|
||||
|
||||
This command is still a work in progress and is considered
|
||||
experimental. Stay away from it unless you want to help with its
|
||||
development.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "id": Name of the block backend device to delete (json-string, optional)
|
||||
- "node-name": Name of the graph node to delete (json-string, optional)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "blockdev-add",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"driver": "qcow2",
|
||||
"id": "drive0",
|
||||
"file": {
|
||||
"driver": "file",
|
||||
"filename": "test.qcow2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<- { "return": {} }
|
||||
|
||||
-> { "execute": "x-blockdev-del",
|
||||
"arguments": { "id": "drive0" }
|
||||
}
|
||||
<- { "return": {} }
|
||||
|
||||
EQMP
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user