From: Zhu Yangyang <zhuyangyang14@huawei.com>
Calling qmp_block_resize() will be blocked for a long time on bdrv_drained_begin()
when a network disk is configured and the network failure is just about
to occur.
Therefore, we add a timeout parameter for qmp_block_resize() to control its
execution duration.
The default value of timeout is 0, that is infinite wait, consistent with
previous behavior.
Signed-off-by: Zhu Yangyang <zhuyangyang14@huawei.com>
---
block/monitor/block-hmp-cmds.c | 2 +-
blockdev.c | 16 ++++++++++++++--
qapi/block-core.json | 6 +++++-
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 6919a49bf5..c24574d950 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -486,7 +486,7 @@ void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
int64_t size = qdict_get_int(qdict, "size");
Error *err = NULL;
- qmp_block_resize(device, NULL, size, &err);
+ qmp_block_resize(device, NULL, size, false, 0, &err);
hmp_handle_error(mon, err);
}
diff --git a/blockdev.c b/blockdev.c
index 1d1f27cfff..d1314f4e2a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2252,12 +2252,15 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
}
void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
- int64_t size, Error **errp)
+ int64_t size,
+ bool has_timeout, uint32_t timeout,
+ Error **errp)
{
Error *local_err = NULL;
BlockBackend *blk;
BlockDriverState *bs;
AioContext *old_ctx;
+ uint64_t timeout_ns;
bs = bdrv_lookup_bs(device, node_name, &local_err);
if (local_err) {
@@ -2282,12 +2285,21 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
return;
}
- bdrv_drained_begin(bs);
+ /* Default is 0, that means infinite */
+ timeout_ns = 0;
+ if (has_timeout) {
+ timeout_ns = timeout * NANOSECONDS_PER_SECOND;
+ }
+ if (bdrv_drained_begin_timeout(bs, timeout_ns) < 0) {
+ error_setg(errp, "command timed out");
+ goto out;
+ }
old_ctx = bdrv_co_enter(bs);
blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
bdrv_co_leave(bs, old_ctx);
+out:
bdrv_drained_end(bs);
blk_co_unref(blk);
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index a75ff1cb0c..2ddff59835 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1460,6 +1460,9 @@
#
# @size: new image size in bytes
#
+# @timeout: In seconds. Timeout for block_resize,
+# 0 means no limit. Defaults to 0. (Since 10.1)
+#
# Errors:
# - If @device is not a valid block device, DeviceNotFound
#
@@ -1474,7 +1477,8 @@
{ 'command': 'block_resize',
'data': { '*device': 'str',
'*node-name': 'str',
- 'size': 'int' },
+ 'size': 'int',
+ '*timeout': 'uint32' },
'coroutine': true,
'allow-preconfig': true }
--
2.33.0