In some scenarios, when copy-before-write operations lasts too long
time, it's better to cancel it.
Most useful would be to use the new option together with
on-cbw-error=break-snapshot: this way if cbw operation takes too long
time we'll just cancel backup process but do not disturb the guest too
much.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org>
---
block/copy-before-write.c | 6 +++++-
qapi/block-core.json | 5 ++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 7ef3f9f4c1..0ea5506f77 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -42,6 +42,7 @@ typedef struct BDRVCopyBeforeWriteState {
BlockCopyState *bcs;
BdrvChild *target;
OnCbwError on_cbw_error;
+ uint32_t cbw_timeout_ns;
/*
* @lock: protects access to @access_bitmap, @done_bitmap and
@@ -107,7 +108,7 @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
off = QEMU_ALIGN_DOWN(offset, cluster_size);
end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
- ret = block_copy(s->bcs, off, end - off, true, 0);
+ ret = block_copy(s->bcs, off, end - off, true, s->cbw_timeout_ns);
if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
return ret;
}
@@ -412,6 +413,7 @@ static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)
*/
qdict_extract_subqdict(options, NULL, "bitmap");
qdict_del(options, "on-cbw-error");
+ qdict_del(options, "cbw-timeout");
out:
visit_free(v);
@@ -455,6 +457,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
}
s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
ON_CBW_ERROR_BREAK_GUEST_WRITE;
+ s->cbw_timeout_ns = opts->has_cbw_timeout ?
+ opts->cbw_timeout * NANOSECONDS_PER_SECOND : 0;
bs->total_sectors = bs->file->bs->total_sectors;
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 3f08025114..e077506e0f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4207,12 +4207,15 @@
# @on-cbw-error: Behavior on failure of copy-before-write operation.
# Default is @break-guest-write. (Since 7.0)
#
+# @cbw-timeout: Zero means no limit. Non-zero sets the timeout in seconds
+# for copy-before-write operation. Default 0. (Since 7.0)
+#
# Since: 6.2
##
{ 'struct': 'BlockdevOptionsCbw',
'base': 'BlockdevOptionsGenericFormat',
'data': { 'target': 'BlockdevRef', '*bitmap': 'BlockDirtyBitmap',
- '*on-cbw-error': 'OnCbwError' } }
+ '*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32' } }
##
# @BlockdevOptions:
--
2.35.1
On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote:
> In some scenarios, when copy-before-write operations lasts too long
> time, it's better to cancel it.
>
> Most useful would be to use the new option together with
> on-cbw-error=break-snapshot: this way if cbw operation takes too long
> time we'll just cancel backup process but do not disturb the guest too
> much.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org>
> ---
> block/copy-before-write.c | 6 +++++-
> qapi/block-core.json | 5 ++++-
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/block/copy-before-write.c b/block/copy-before-write.c
> index 7ef3f9f4c1..0ea5506f77 100644
> --- a/block/copy-before-write.c
> +++ b/block/copy-before-write.c
> @@ -42,6 +42,7 @@ typedef struct BDRVCopyBeforeWriteState {
> BlockCopyState *bcs;
> BdrvChild *target;
> OnCbwError on_cbw_error;
> + uint32_t cbw_timeout_ns;
>
> /*
> * @lock: protects access to @access_bitmap, @done_bitmap and
> @@ -107,7 +108,7 @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
> off = QEMU_ALIGN_DOWN(offset, cluster_size);
> end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
>
> - ret = block_copy(s->bcs, off, end - off, true, 0);
> + ret = block_copy(s->bcs, off, end - off, true, s->cbw_timeout_ns);
> if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
> return ret;
> }
> @@ -412,6 +413,7 @@ static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp)
> */
> qdict_extract_subqdict(options, NULL, "bitmap");
> qdict_del(options, "on-cbw-error");
> + qdict_del(options, "cbw-timeout");
>
> out:
> visit_free(v);
> @@ -455,6 +457,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
> }
> s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
> ON_CBW_ERROR_BREAK_GUEST_WRITE;
> + s->cbw_timeout_ns = opts->has_cbw_timeout ?
> + opts->cbw_timeout * NANOSECONDS_PER_SECOND : 0;
>
> bs->total_sectors = bs->file->bs->total_sectors;
> bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 3f08025114..e077506e0f 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -4207,12 +4207,15 @@
> # @on-cbw-error: Behavior on failure of copy-before-write operation.
> # Default is @break-guest-write. (Since 7.0)
> #
> +# @cbw-timeout: Zero means no limit. Non-zero sets the timeout in seconds
> +# for copy-before-write operation. Default 0. (Since 7.0)
*7.1, but:
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
> +#
> # Since: 6.2
> ##
> { 'struct': 'BlockdevOptionsCbw',
> 'base': 'BlockdevOptionsGenericFormat',
> 'data': { 'target': 'BlockdevRef', '*bitmap': 'BlockDirtyBitmap',
> - '*on-cbw-error': 'OnCbwError' } }
> + '*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32' } }
>
> ##
> # @BlockdevOptions:
On 01.04.22 15:24, Hanna Reitz wrote: > On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote: >> In some scenarios, when copy-before-write operations lasts too long >> time, it's better to cancel it. >> >> Most useful would be to use the new option together with >> on-cbw-error=break-snapshot: this way if cbw operation takes too long >> time we'll just cancel backup process but do not disturb the guest too >> much. >> >> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org> >> --- >> block/copy-before-write.c | 6 +++++- >> qapi/block-core.json | 5 ++++- >> 2 files changed, 9 insertions(+), 2 deletions(-) >> [...] >> diff --git a/qapi/block-core.json b/qapi/block-core.json >> index 3f08025114..e077506e0f 100644 >> --- a/qapi/block-core.json >> +++ b/qapi/block-core.json >> @@ -4207,12 +4207,15 @@ >> # @on-cbw-error: Behavior on failure of copy-before-write operation. >> # Default is @break-guest-write. (Since 7.0) >> # >> +# @cbw-timeout: Zero means no limit. Non-zero sets the timeout in >> seconds >> +# for copy-before-write operation. Default 0. (Since 7.0) > > *7.1, but: > > Reviewed-by: Hanna Reitz <hreitz@redhat.com> On second thought, perhaps we should make an explicit note that a timeout means an error? E.g. “When a timeout occurs, the respective copy-before-write operation will fail, and the @on-cbw-error parameter will decide how this failure is handled.” (Optional, R-b stands without it, too)
01.04.2022 16:28, Hanna Reitz wrote: > On 01.04.22 15:24, Hanna Reitz wrote: >> On 01.04.22 11:19, Vladimir Sementsov-Ogievskiy wrote: >>> In some scenarios, when copy-before-write operations lasts too long >>> time, it's better to cancel it. >>> >>> Most useful would be to use the new option together with >>> on-cbw-error=break-snapshot: this way if cbw operation takes too long >>> time we'll just cancel backup process but do not disturb the guest too >>> much. >>> >>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org> >>> --- >>> block/copy-before-write.c | 6 +++++- >>> qapi/block-core.json | 5 ++++- >>> 2 files changed, 9 insertions(+), 2 deletions(-) >>> > > [...] > >>> diff --git a/qapi/block-core.json b/qapi/block-core.json >>> index 3f08025114..e077506e0f 100644 >>> --- a/qapi/block-core.json >>> +++ b/qapi/block-core.json >>> @@ -4207,12 +4207,15 @@ >>> # @on-cbw-error: Behavior on failure of copy-before-write operation. >>> # Default is @break-guest-write. (Since 7.0) >>> # >>> +# @cbw-timeout: Zero means no limit. Non-zero sets the timeout in seconds >>> +# for copy-before-write operation. Default 0. (Since 7.0) >> >> *7.1, but: >> >> Reviewed-by: Hanna Reitz <hreitz@redhat.com> > > On second thought, perhaps we should make an explicit note that a timeout means an error? E.g. “When a timeout occurs, the respective copy-before-write operation will fail, and the @on-cbw-error parameter will decide how this failure is handled.” > Agree, worth noting, will add. -- Best regards, Vladimir
© 2016 - 2026 Red Hat, Inc.