mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
block: Remove BB interface from blockdev-add/del
With this patch, blockdev-add always works on a node level, i.e. it creates a BDS, but no BB. Consequently, x-blockdev-del doesn't need the 'device' option any more, but 'node-name' becomes mandatory. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
7864588150
commit
9ec8873e68
4 changed files with 50 additions and 134 deletions
128
blockdev.c
128
blockdev.c
|
@ -2844,7 +2844,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
|||
|
||||
bs = bdrv_find_node(id);
|
||||
if (bs) {
|
||||
qmp_x_blockdev_del(false, NULL, true, id, &local_err);
|
||||
qmp_x_blockdev_del(id, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
|
@ -3827,7 +3827,6 @@ out:
|
|||
void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
BlockBackend *blk = NULL;
|
||||
QObject *obj;
|
||||
Visitor *v = qmp_output_visitor_new(&obj);
|
||||
QDict *qdict;
|
||||
|
@ -3859,37 +3858,21 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
|||
|
||||
qdict_flatten(qdict);
|
||||
|
||||
if (options->has_id) {
|
||||
blk = blockdev_init(NULL, qdict, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = blk_bs(blk);
|
||||
} else {
|
||||
if (!qdict_get_try_str(qdict, "node-name")) {
|
||||
error_setg(errp, "'id' and/or 'node-name' need to be specified for "
|
||||
"the root node");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bds_tree_init(qdict, errp);
|
||||
if (!bs) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
if (!qdict_get_try_str(qdict, "node-name")) {
|
||||
error_setg(errp, "'node-name' must be specified for the root node");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bds_tree_init(qdict, errp);
|
||||
if (!bs) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
|
||||
if (bs && bdrv_key_required(bs)) {
|
||||
if (blk) {
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
} else {
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
error_setg(errp, "blockdev-add doesn't support encrypted devices");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -3898,81 +3881,42 @@ fail:
|
|||
visit_free(v);
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_del(bool has_id, const char *id,
|
||||
bool has_node_name, const char *node_name, Error **errp)
|
||||
void qmp_x_blockdev_del(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");
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Cannot find node %s", node_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_id) {
|
||||
/* blk_by_name() never returns a BB that is not owned by the monitor */
|
||||
blk = blk_by_name(id);
|
||||
if (!blk) {
|
||||
error_setg(errp, "Cannot find block backend %s", id);
|
||||
return;
|
||||
}
|
||||
if (blk_legacy_dinfo(blk)) {
|
||||
error_setg(errp, "Deleting block backend added with drive-add"
|
||||
" is not supported");
|
||||
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 {
|
||||
blk = NULL;
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Cannot find node %s", node_name);
|
||||
return;
|
||||
}
|
||||
if (bdrv_has_blk(bs)) {
|
||||
error_setg(errp, "Node %s is in use", node_name);
|
||||
return;
|
||||
}
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
if (bdrv_has_blk(bs)) {
|
||||
error_setg(errp, "Node %s is in use", node_name);
|
||||
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 (!blk && !QTAILQ_IN_USE(bs, monitor_list)) {
|
||||
error_setg(errp, "Node %s is not owned by the monitor",
|
||||
bs->node_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bs->refcnt > 1) {
|
||||
error_setg(errp, "Block device %s is in use",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
goto out;
|
||||
}
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (blk) {
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
} else {
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
if (!bs->monitor_list.tqe_prev) {
|
||||
error_setg(errp, "Node %s is not owned by the monitor",
|
||||
bs->node_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bs->refcnt > 1) {
|
||||
error_setg(errp, "Block device %s is in use",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
goto out;
|
||||
}
|
||||
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue