51232e2e40
The type for the copy-before-write timeout in nanoseconds was wrong. By being just uint32_t, a maximum of slightly over 4 seconds was possible. Larger values would overflow and thus the 45 seconds set by Proxmox's backup with fleecing, resulted in effectively 2 seconds timeout for copy-before-write operations. Reported-by: Friedrich Weber <f.weber@proxmox.com> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
107 lines
4.3 KiB
Diff
107 lines
4.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Fiona Ebner <f.ebner@proxmox.com>
|
|
Date: Thu, 11 Apr 2024 11:29:27 +0200
|
|
Subject: [PATCH] backup: add minimum cluster size to performance options
|
|
|
|
Useful to make discard-source work in the context of backup fleecing
|
|
when the fleecing image has a larger granularity than the backup
|
|
target.
|
|
|
|
Backup/block-copy will use at least this granularity for copy operations
|
|
and in particular, discard requests to the backup source will too. If
|
|
the granularity is too small, they will just be aligned down in
|
|
cbw_co_pdiscard_snapshot() and thus effectively ignored.
|
|
|
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|
---
|
|
block/backup.c | 2 +-
|
|
block/copy-before-write.c | 2 ++
|
|
block/copy-before-write.h | 1 +
|
|
blockdev.c | 3 +++
|
|
qapi/block-core.json | 9 +++++++--
|
|
5 files changed, 14 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/block/backup.c b/block/backup.c
|
|
index 1963e47ab9..fe69723ada 100644
|
|
--- a/block/backup.c
|
|
+++ b/block/backup.c
|
|
@@ -434,7 +434,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
}
|
|
|
|
cbw = bdrv_cbw_append(bs, target, filter_node_name, discard_source,
|
|
- &bcs, errp);
|
|
+ perf->min_cluster_size, &bcs, errp);
|
|
if (!cbw) {
|
|
goto error;
|
|
}
|
|
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
|
|
index 47b3cdd09f..bba58326d7 100644
|
|
--- a/block/copy-before-write.c
|
|
+++ b/block/copy-before-write.c
|
|
@@ -546,6 +546,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
|
BlockDriverState *target,
|
|
const char *filter_node_name,
|
|
bool discard_source,
|
|
+ int64_t min_cluster_size,
|
|
BlockCopyState **bcs,
|
|
Error **errp)
|
|
{
|
|
@@ -564,6 +565,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
|
}
|
|
qdict_put_str(opts, "file", bdrv_get_node_name(source));
|
|
qdict_put_str(opts, "target", bdrv_get_node_name(target));
|
|
+ qdict_put_int(opts, "min-cluster-size", min_cluster_size);
|
|
|
|
top = bdrv_insert_node(source, opts, flags, errp);
|
|
if (!top) {
|
|
diff --git a/block/copy-before-write.h b/block/copy-before-write.h
|
|
index 01af0cd3c4..dc6cafe7fa 100644
|
|
--- a/block/copy-before-write.h
|
|
+++ b/block/copy-before-write.h
|
|
@@ -40,6 +40,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
|
|
BlockDriverState *target,
|
|
const char *filter_node_name,
|
|
bool discard_source,
|
|
+ int64_t min_cluster_size,
|
|
BlockCopyState **bcs,
|
|
Error **errp);
|
|
void bdrv_cbw_drop(BlockDriverState *bs);
|
|
diff --git a/blockdev.c b/blockdev.c
|
|
index 1054a69279..cbe224387b 100644
|
|
--- a/blockdev.c
|
|
+++ b/blockdev.c
|
|
@@ -2654,6 +2654,9 @@ static BlockJob *do_backup_common(BackupCommon *backup,
|
|
if (backup->x_perf->has_max_chunk) {
|
|
perf.max_chunk = backup->x_perf->max_chunk;
|
|
}
|
|
+ if (backup->x_perf->has_min_cluster_size) {
|
|
+ perf.min_cluster_size = backup->x_perf->min_cluster_size;
|
|
+ }
|
|
}
|
|
|
|
if ((backup->sync == MIRROR_SYNC_MODE_BITMAP) ||
|
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
|
index edbf6e78b9..6e7ee87633 100644
|
|
--- a/qapi/block-core.json
|
|
+++ b/qapi/block-core.json
|
|
@@ -1790,11 +1790,16 @@
|
|
# it should not be less than job cluster size which is calculated
|
|
# as maximum of target image cluster size and 64k. Default 0.
|
|
#
|
|
+# @min-cluster-size: Minimum size of blocks used by copy-before-write
|
|
+# and background copy operations. Has to be a power of 2. No
|
|
+# effect if smaller than the maximum of the target's cluster size
|
|
+# and 64 KiB. Default 0. (Since 8.1)
|
|
+#
|
|
# Since: 6.0
|
|
##
|
|
{ 'struct': 'BackupPerf',
|
|
- 'data': { '*use-copy-range': 'bool',
|
|
- '*max-workers': 'int', '*max-chunk': 'int64' } }
|
|
+ 'data': { '*use-copy-range': 'bool', '*max-workers': 'int',
|
|
+ '*max-chunk': 'int64', '*min-cluster-size': 'uint32' } }
|
|
|
|
##
|
|
# @BackupCommon:
|