Default behavior is force=true and it's unchanged. New behavior is force=false, which makes it possible to be sure that node removal is done successfully with no error and all metadata is stored and flushed successfully.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- qapi/block-core.json | 6 +++++- block/monitor/block-hmp-cmds.c | 2 +- blockdev.c | 17 +++++++++++++++-- hw/block/xen-block.c | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 9a5a3641d0..b37d195772 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -4403,6 +4403,9 @@ # # @node-name: Name of the graph node to delete. # +# @force: Ignore failures when closing block-nodes, like failed IO +# when try to store metadata. Default true. (Since 7.0) +# # Since: 2.9 # # Example: @@ -4425,7 +4428,8 @@ # <- { "return": {} } # ## -{ 'command': 'blockdev-del', 'data': { 'node-name': 'str' } } +{ 'command': 'blockdev-del', + 'data': { 'node-name': 'str', '*force': 'bool' } } ## # @BlockdevCreateOptionsFile: diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index bfb3c043a0..1c35aa2d6f 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -145,7 +145,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict) bs = bdrv_find_node(id); if (bs) { - qmp_blockdev_del(id, &local_err); + qmp_blockdev_del(id, true, true, &local_err); if (local_err) { error_report_err(local_err); } diff --git a/blockdev.c b/blockdev.c index 8197165bb5..34a195b592 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3582,11 +3582,17 @@ fail: g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end); } -void qmp_blockdev_del(const char *node_name, Error **errp) +void qmp_blockdev_del(const char *node_name, bool has_force, + bool force, Error **errp) { AioContext *aio_context; BlockDriverState *bs; + if (!has_force) { + /* Historical default is force remove */ + force = true; + } + bs = bdrv_find_node(node_name); if (!bs) { error_setg(errp, "Failed to find node with node-name='%s'", node_name); @@ -3616,7 +3622,14 @@ void qmp_blockdev_del(const char *node_name, Error **errp) } QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list); - bdrv_unref(bs); + if (force) { + bdrv_unref(bs); + } else { + int ret = bdrv_try_unref(bs, errp); + if (ret < 0) { + bdrv_set_monitor_owned(bs); + } + } out: aio_context_release(aio_context); diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 674953f1ad..0ac9b599c0 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -649,7 +649,7 @@ static void xen_block_blockdev_del(const char *node_name, Error **errp) { trace_xen_block_blockdev_del(node_name); - qmp_blockdev_del(node_name, errp); + qmp_blockdev_del(node_name, true, true, errp); } static char *xen_block_blockdev_add(const char *id, QDict *qdict, -- 2.31.1