add bitmap drive-mirror patches
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
66e3df5d45
commit
059a9447e2
443
debian/patches/pve/0034-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
vendored
Normal file
443
debian/patches/pve/0034-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
vendored
Normal file
@ -0,0 +1,443 @@
|
||||
From 1bfdb0492d8b70983342cf96576b294d60172e05 Mon Sep 17 00:00:00 2001
|
||||
From: John Snow <jsnow@redhat.com>
|
||||
Date: Tue, 9 Jul 2019 21:12:21 -0400
|
||||
Subject: [PATCH qemu 34/39] drive-mirror: add support for sync=bitmap
|
||||
mode=never
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds support for the "BITMAP" sync mode to drive-mirror and
|
||||
blockdev-mirror. It adds support only for the BitmapSyncMode "never,"
|
||||
because it's the simplest mode.
|
||||
|
||||
This mode simply uses a user-provided bitmap as an initial copy
|
||||
manifest, and then does not clear any bits in the bitmap at the
|
||||
conclusion of the operation.
|
||||
|
||||
Any new writes dirtied during the operation are copied out, in contrast
|
||||
to backup. Note that whether these writes are reflected in the bitmap
|
||||
at the conclusion of the operation depends on whether that bitmap is
|
||||
actually recording!
|
||||
|
||||
This patch was originally based on one by Ma Haocong, but it has since
|
||||
been modified pretty heavily.
|
||||
|
||||
Suggested-by: Ma Haocong <mahaocong@didichuxing.com>
|
||||
Signed-off-by: Ma Haocong <mahaocong@didichuxing.com>
|
||||
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
---
|
||||
include/block/block_int.h | 4 +-
|
||||
block/mirror.c | 98 ++++++++++++++++++++++++++++++-------
|
||||
blockdev.c | 39 +++++++++++++--
|
||||
tests/test-block-iothread.c | 4 +-
|
||||
qapi/block-core.json | 29 +++++++++--
|
||||
5 files changed, 145 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/include/block/block_int.h b/include/block/block_int.h
|
||||
index 43b00c15ac..bd2e11c4d9 100644
|
||||
--- a/include/block/block_int.h
|
||||
+++ b/include/block/block_int.h
|
||||
@@ -1206,7 +1206,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target, const char *replaces,
|
||||
int creation_flags, int64_t speed,
|
||||
uint32_t granularity, int64_t buf_size,
|
||||
- MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
|
||||
+ MirrorSyncMode mode, BdrvDirtyBitmap *bitmap,
|
||||
+ BitmapSyncMode bitmap_mode,
|
||||
+ BlockMirrorBackingMode backing_mode,
|
||||
bool zero_target,
|
||||
BlockdevOnError on_source_error,
|
||||
BlockdevOnError on_target_error,
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index f0f2d9dff1..fd7f574365 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -49,7 +49,7 @@ typedef struct MirrorBlockJob {
|
||||
BlockDriverState *to_replace;
|
||||
/* Used to block operations on the drive-mirror-replace target */
|
||||
Error *replace_blocker;
|
||||
- bool is_none_mode;
|
||||
+ MirrorSyncMode sync_mode;
|
||||
BlockMirrorBackingMode backing_mode;
|
||||
/* Whether the target image requires explicit zero-initialization */
|
||||
bool zero_target;
|
||||
@@ -64,6 +64,8 @@ typedef struct MirrorBlockJob {
|
||||
size_t buf_size;
|
||||
int64_t bdev_length;
|
||||
unsigned long *cow_bitmap;
|
||||
+ BdrvDirtyBitmap *sync_bitmap;
|
||||
+ BitmapSyncMode bitmap_mode;
|
||||
BdrvDirtyBitmap *dirty_bitmap;
|
||||
BdrvDirtyBitmapIter *dbi;
|
||||
uint8_t *buf;
|
||||
@@ -668,7 +670,8 @@ static int mirror_exit_common(Job *job)
|
||||
bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
|
||||
&error_abort);
|
||||
if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
|
||||
- BlockDriverState *backing = s->is_none_mode ? src : s->base;
|
||||
+ BlockDriverState *backing;
|
||||
+ backing = s->sync_mode == MIRROR_SYNC_MODE_NONE ? src : s->base;
|
||||
if (backing_bs(target_bs) != backing) {
|
||||
bdrv_set_backing_hd(target_bs, backing, &local_err);
|
||||
if (local_err) {
|
||||
@@ -750,6 +753,16 @@ static void mirror_abort(Job *job)
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
+/* Always called after commit/abort. */
|
||||
+static void mirror_clean(Job *job)
|
||||
+{
|
||||
+ MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||
+
|
||||
+ if (s->sync_bitmap) {
|
||||
+ bdrv_dirty_bitmap_set_busy(s->sync_bitmap, false);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
|
||||
{
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
@@ -928,7 +941,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
mirror_free_init(s);
|
||||
|
||||
s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
- if (!s->is_none_mode) {
|
||||
+ if ((s->sync_mode == MIRROR_SYNC_MODE_TOP) ||
|
||||
+ (s->sync_mode == MIRROR_SYNC_MODE_FULL)) {
|
||||
ret = mirror_dirty_init(s);
|
||||
if (ret < 0 || job_is_cancelled(&s->common.job)) {
|
||||
goto immediate_exit;
|
||||
@@ -1160,6 +1174,7 @@ static const BlockJobDriver mirror_job_driver = {
|
||||
.run = mirror_run,
|
||||
.prepare = mirror_prepare,
|
||||
.abort = mirror_abort,
|
||||
+ .clean = mirror_clean,
|
||||
.pause = mirror_pause,
|
||||
.complete = mirror_complete,
|
||||
},
|
||||
@@ -1175,6 +1190,7 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||
.run = mirror_run,
|
||||
.prepare = mirror_prepare,
|
||||
.abort = mirror_abort,
|
||||
+ .clean = mirror_clean,
|
||||
.pause = mirror_pause,
|
||||
.complete = mirror_complete,
|
||||
},
|
||||
@@ -1520,7 +1536,10 @@ static BlockJob *mirror_start_job(
|
||||
BlockCompletionFunc *cb,
|
||||
void *opaque,
|
||||
const BlockJobDriver *driver,
|
||||
- bool is_none_mode, BlockDriverState *base,
|
||||
+ MirrorSyncMode sync_mode,
|
||||
+ BdrvDirtyBitmap *bitmap,
|
||||
+ BitmapSyncMode bitmap_mode,
|
||||
+ BlockDriverState *base,
|
||||
bool auto_complete, const char *filter_node_name,
|
||||
bool is_mirror, MirrorCopyMode copy_mode,
|
||||
Error **errp)
|
||||
@@ -1533,10 +1552,39 @@ static BlockJob *mirror_start_job(
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
- if (granularity == 0) {
|
||||
- granularity = bdrv_get_default_bitmap_granularity(target);
|
||||
+ if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
|
||||
+ error_setg(errp, "Sync mode '%s' not supported",
|
||||
+ MirrorSyncMode_str(sync_mode));
|
||||
+ return NULL;
|
||||
+ } else if (sync_mode == MIRROR_SYNC_MODE_BITMAP) {
|
||||
+ if (!bitmap) {
|
||||
+ error_setg(errp, "Must provide a valid bitmap name for '%s'"
|
||||
+ " sync mode",
|
||||
+ MirrorSyncMode_str(sync_mode));
|
||||
+ return NULL;
|
||||
+ } else if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||
+ error_setg(errp,
|
||||
+ "Bitmap Sync Mode '%s' is not supported by Mirror",
|
||||
+ BitmapSyncMode_str(bitmap_mode));
|
||||
+ }
|
||||
+ } else if (bitmap) {
|
||||
+ error_setg(errp,
|
||||
+ "sync mode '%s' is not compatible with bitmaps",
|
||||
+ MirrorSyncMode_str(sync_mode));
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
+ if (bitmap) {
|
||||
+ if (granularity) {
|
||||
+ error_setg(errp, "granularity (%d)"
|
||||
+ "cannot be specified when a bitmap is provided",
|
||||
+ granularity);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ granularity = bdrv_dirty_bitmap_granularity(bitmap);
|
||||
+ } else if (granularity == 0) {
|
||||
+ granularity = bdrv_get_default_bitmap_granularity(target);
|
||||
+ }
|
||||
assert(is_power_of_2(granularity));
|
||||
|
||||
if (buf_size < 0) {
|
||||
@@ -1640,7 +1688,9 @@ static BlockJob *mirror_start_job(
|
||||
s->replaces = g_strdup(replaces);
|
||||
s->on_source_error = on_source_error;
|
||||
s->on_target_error = on_target_error;
|
||||
- s->is_none_mode = is_none_mode;
|
||||
+ s->sync_mode = sync_mode;
|
||||
+ s->sync_bitmap = bitmap;
|
||||
+ s->bitmap_mode = bitmap_mode;
|
||||
s->backing_mode = backing_mode;
|
||||
s->zero_target = zero_target;
|
||||
s->copy_mode = copy_mode;
|
||||
@@ -1660,6 +1710,18 @@ static BlockJob *mirror_start_job(
|
||||
bdrv_disable_dirty_bitmap(s->dirty_bitmap);
|
||||
}
|
||||
|
||||
+ if (s->sync_bitmap) {
|
||||
+ bdrv_dirty_bitmap_set_busy(s->sync_bitmap, true);
|
||||
+ }
|
||||
+
|
||||
+ if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
|
||||
+ bdrv_merge_dirty_bitmap(s->dirty_bitmap, s->sync_bitmap,
|
||||
+ NULL, &local_err);
|
||||
+ if (local_err) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
|
||||
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
|
||||
BLK_PERM_CONSISTENT_READ,
|
||||
@@ -1713,6 +1775,9 @@ fail:
|
||||
if (s->dirty_bitmap) {
|
||||
bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
}
|
||||
+ if (s->sync_bitmap) {
|
||||
+ bdrv_dirty_bitmap_set_busy(s->sync_bitmap, false);
|
||||
+ }
|
||||
job_early_fail(&s->common.job);
|
||||
}
|
||||
|
||||
@@ -1730,29 +1795,23 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target, const char *replaces,
|
||||
int creation_flags, int64_t speed,
|
||||
uint32_t granularity, int64_t buf_size,
|
||||
- MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
|
||||
+ MirrorSyncMode mode, BdrvDirtyBitmap *bitmap,
|
||||
+ BitmapSyncMode bitmap_mode,
|
||||
+ BlockMirrorBackingMode backing_mode,
|
||||
bool zero_target,
|
||||
BlockdevOnError on_source_error,
|
||||
BlockdevOnError on_target_error,
|
||||
bool unmap, const char *filter_node_name,
|
||||
MirrorCopyMode copy_mode, Error **errp)
|
||||
{
|
||||
- bool is_none_mode;
|
||||
BlockDriverState *base;
|
||||
|
||||
- if ((mode == MIRROR_SYNC_MODE_INCREMENTAL) ||
|
||||
- (mode == MIRROR_SYNC_MODE_BITMAP)) {
|
||||
- error_setg(errp, "Sync mode '%s' not supported",
|
||||
- MirrorSyncMode_str(mode));
|
||||
- return;
|
||||
- }
|
||||
- is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
|
||||
base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
|
||||
mirror_start_job(job_id, bs, creation_flags, target, replaces,
|
||||
speed, granularity, buf_size, backing_mode, zero_target,
|
||||
on_source_error, on_target_error, unmap, NULL, NULL,
|
||||
- &mirror_job_driver, is_none_mode, base, false,
|
||||
- filter_node_name, true, copy_mode, errp);
|
||||
+ &mirror_job_driver, mode, bitmap, bitmap_mode, base,
|
||||
+ false, filter_node_name, true, copy_mode, errp);
|
||||
}
|
||||
|
||||
BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
@@ -1778,7 +1837,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
job_id, bs, creation_flags, base, NULL, speed, 0, 0,
|
||||
MIRROR_LEAVE_BACKING_CHAIN, false,
|
||||
on_error, on_error, true, cb, opaque,
|
||||
- &commit_active_job_driver, false, base, auto_complete,
|
||||
+ &commit_active_job_driver, MIRROR_SYNC_MODE_FULL,
|
||||
+ NULL, 0, base, auto_complete,
|
||||
filter_node_name, false, MIRROR_COPY_MODE_BACKGROUND,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index e5310cb939..08285b9e86 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -3763,6 +3763,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target,
|
||||
bool has_replaces, const char *replaces,
|
||||
enum MirrorSyncMode sync,
|
||||
+ bool has_bitmap,
|
||||
+ const char *bitmap_name,
|
||||
+ bool has_bitmap_mode,
|
||||
+ BitmapSyncMode bitmap_mode,
|
||||
BlockMirrorBackingMode backing_mode,
|
||||
bool zero_target,
|
||||
bool has_speed, int64_t speed,
|
||||
@@ -3781,6 +3785,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
int job_flags = JOB_DEFAULT;
|
||||
+ BdrvDirtyBitmap *bitmap = NULL;
|
||||
|
||||
if (!has_speed) {
|
||||
speed = 0;
|
||||
@@ -3835,6 +3840,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
|
||||
+ if (has_bitmap) {
|
||||
+ if (granularity) {
|
||||
+ error_setg(errp, "Granularity and bitmap cannot both be set");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!has_bitmap_mode) {
|
||||
+ error_setg(errp, "bitmap-mode must be specified if"
|
||||
+ " a bitmap is provided");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bitmap = bdrv_find_dirty_bitmap(bs, bitmap_name);
|
||||
+ if (!bitmap) {
|
||||
+ error_setg(errp, "Dirty bitmap '%s' not found", bitmap_name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (has_replaces) {
|
||||
BlockDriverState *to_replace_bs;
|
||||
AioContext *replace_aio_context;
|
||||
@@ -3872,8 +3900,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
* and will allow to check whether the node still exist at mirror completion
|
||||
*/
|
||||
mirror_start(job_id, bs, target,
|
||||
- has_replaces ? replaces : NULL, job_flags,
|
||||
- speed, granularity, buf_size, sync, backing_mode, zero_target,
|
||||
+ has_replaces ? replaces : NULL, job_flags, speed, granularity,
|
||||
+ buf_size, sync, bitmap, bitmap_mode, backing_mode, zero_target,
|
||||
on_source_error, on_target_error, unmap, filter_node_name,
|
||||
copy_mode, errp);
|
||||
}
|
||||
@@ -4003,6 +4031,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
|
||||
blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
|
||||
arg->has_replaces, arg->replaces, arg->sync,
|
||||
+ arg->has_bitmap, arg->bitmap,
|
||||
+ arg->has_bitmap_mode, arg->bitmap_mode,
|
||||
backing_mode, zero_target,
|
||||
arg->has_speed, arg->speed,
|
||||
arg->has_granularity, arg->granularity,
|
||||
@@ -4025,6 +4055,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
|
||||
const char *device, const char *target,
|
||||
bool has_replaces, const char *replaces,
|
||||
MirrorSyncMode sync,
|
||||
+ bool has_bitmap, const char *bitmap,
|
||||
+ bool has_bitmap_mode, BitmapSyncMode bitmap_mode,
|
||||
bool has_speed, int64_t speed,
|
||||
bool has_granularity, uint32_t granularity,
|
||||
bool has_buf_size, int64_t buf_size,
|
||||
@@ -4068,7 +4100,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
|
||||
}
|
||||
|
||||
blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
|
||||
- has_replaces, replaces, sync, backing_mode,
|
||||
+ has_replaces, replaces, sync, has_bitmap,
|
||||
+ bitmap, has_bitmap_mode, bitmap_mode, backing_mode,
|
||||
zero_target, has_speed, speed,
|
||||
has_granularity, granularity,
|
||||
has_buf_size, buf_size,
|
||||
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
|
||||
index 0c861809f0..da87a67a57 100644
|
||||
--- a/tests/test-block-iothread.c
|
||||
+++ b/tests/test-block-iothread.c
|
||||
@@ -611,8 +611,8 @@ static void test_propagate_mirror(void)
|
||||
|
||||
/* Start a mirror job */
|
||||
mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
|
||||
- MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false,
|
||||
- BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
|
||||
+ MIRROR_SYNC_MODE_NONE, NULL, 0, MIRROR_OPEN_BACKING_CHAIN,
|
||||
+ false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
|
||||
false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
|
||||
&error_abort);
|
||||
job = job_get("job0");
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 0b987ad6e3..e2050bab1d 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -2086,10 +2086,19 @@
|
||||
# (all the disk, only the sectors allocated in the topmost image, or
|
||||
# only new I/O).
|
||||
#
|
||||
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This argument must
|
||||
+# be present for bitmap mode and absent otherwise. The bitmap's
|
||||
+# granularity is used instead of @granularity (since 4.1).
|
||||
+#
|
||||
+# @bitmap-mode: Specifies the type of data the bitmap should contain after
|
||||
+# the operation concludes. Must be present if sync is "bitmap".
|
||||
+# Must NOT be present otherwise. (Since 4.1)
|
||||
+#
|
||||
# @granularity: granularity of the dirty bitmap, default is 64K
|
||||
# if the image format doesn't have clusters, 4K if the clusters
|
||||
# are smaller than that, else the cluster size. Must be a
|
||||
-# power of 2 between 512 and 64M (since 1.4).
|
||||
+# power of 2 between 512 and 64M. Must not be specified if
|
||||
+# @bitmap is present (since 1.4).
|
||||
#
|
||||
# @buf-size: maximum amount of data in flight from source to
|
||||
# target (since 1.4).
|
||||
@@ -2127,7 +2136,9 @@
|
||||
{ 'struct': 'DriveMirror',
|
||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||
'*format': 'str', '*node-name': 'str', '*replaces': 'str',
|
||||
- 'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
|
||||
+ 'sync': 'MirrorSyncMode', '*bitmap': 'str',
|
||||
+ '*bitmap-mode': 'BitmapSyncMode',
|
||||
+ '*mode': 'NewImageMode',
|
||||
'*speed': 'int', '*granularity': 'uint32',
|
||||
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
||||
'*on-target-error': 'BlockdevOnError',
|
||||
@@ -2394,10 +2405,19 @@
|
||||
# (all the disk, only the sectors allocated in the topmost image, or
|
||||
# only new I/O).
|
||||
#
|
||||
+# @bitmap: The name of a bitmap to use for sync=bitmap mode. This argument must
|
||||
+# be present for bitmap mode and absent otherwise. The bitmap's
|
||||
+# granularity is used instead of @granularity (since 4.1).
|
||||
+#
|
||||
+# @bitmap-mode: Specifies the type of data the bitmap should contain after
|
||||
+# the operation concludes. Must be present if sync is "bitmap".
|
||||
+# Must NOT be present otherwise. (Since 4.1)
|
||||
+#
|
||||
# @granularity: granularity of the dirty bitmap, default is 64K
|
||||
# if the image format doesn't have clusters, 4K if the clusters
|
||||
# are smaller than that, else the cluster size. Must be a
|
||||
-# power of 2 between 512 and 64M
|
||||
+# power of 2 between 512 and 64M . Must not be specified if
|
||||
+# @bitmap is present.
|
||||
#
|
||||
# @buf-size: maximum amount of data in flight from source to
|
||||
# target
|
||||
@@ -2446,7 +2466,8 @@
|
||||
{ 'command': 'blockdev-mirror',
|
||||
'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
|
||||
'*replaces': 'str',
|
||||
- 'sync': 'MirrorSyncMode',
|
||||
+ 'sync': 'MirrorSyncMode', '*bitmap': 'str',
|
||||
+ '*bitmap-mode': 'BitmapSyncMode',
|
||||
'*speed': 'int', '*granularity': 'uint32',
|
||||
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
|
||||
'*on-target-error': 'BlockdevOnError',
|
||||
--
|
||||
2.20.1
|
||||
|
83
debian/patches/pve/0035-drive-mirror-add-support-for-conditional-and-always-.patch
vendored
Normal file
83
debian/patches/pve/0035-drive-mirror-add-support-for-conditional-and-always-.patch
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
From 4c46f8b0f6fd8efba5e4d0b738b4f01ffcb92d33 Mon Sep 17 00:00:00 2001
|
||||
From: John Snow <jsnow@redhat.com>
|
||||
Date: Tue, 9 Jul 2019 21:12:30 -0400
|
||||
Subject: [PATCH qemu 35/39] drive-mirror: add support for conditional and
|
||||
always bitmap sync modes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Teach mirror two new tricks for using bitmaps:
|
||||
|
||||
Always: no matter what, we synchronize the copy_bitmap back to the
|
||||
sync_bitmap. In effect, this allows us resume a failed mirror at a later
|
||||
date.
|
||||
|
||||
Conditional: On success only, we sync the bitmap. This is akin to
|
||||
incremental backup modes; we can use this bitmap to later refresh a
|
||||
successfully created mirror.
|
||||
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
---
|
||||
block/mirror.c | 24 ++++++++++++++++++------
|
||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index fd7f574365..40d174a625 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -645,8 +645,6 @@ static int mirror_exit_common(Job *job)
|
||||
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
|
||||
}
|
||||
|
||||
- bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
-
|
||||
/* Make sure that the source BDS doesn't go away during bdrv_replace_node,
|
||||
* before we can call bdrv_drained_end */
|
||||
bdrv_ref(src);
|
||||
@@ -731,6 +729,18 @@ static int mirror_exit_common(Job *job)
|
||||
blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
|
||||
blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
|
||||
|
||||
+ if (s->sync_bitmap) {
|
||||
+ if (s->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS ||
|
||||
+ (s->bitmap_mode == BITMAP_SYNC_MODE_ON_SUCCESS &&
|
||||
+ job->ret == 0 && ret == 0)) {
|
||||
+ /* Success; synchronize copy back to sync. */
|
||||
+ bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL);
|
||||
+ bdrv_merge_dirty_bitmap(s->sync_bitmap, s->dirty_bitmap,
|
||||
+ NULL, &error_abort);
|
||||
+ }
|
||||
+ }
|
||||
+ bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
+
|
||||
bs_opaque->job = NULL;
|
||||
|
||||
bdrv_drained_end(src);
|
||||
@@ -1562,10 +1572,6 @@ static BlockJob *mirror_start_job(
|
||||
" sync mode",
|
||||
MirrorSyncMode_str(sync_mode));
|
||||
return NULL;
|
||||
- } else if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||
- error_setg(errp,
|
||||
- "Bitmap Sync Mode '%s' is not supported by Mirror",
|
||||
- BitmapSyncMode_str(bitmap_mode));
|
||||
}
|
||||
} else if (bitmap) {
|
||||
error_setg(errp,
|
||||
@@ -1582,6 +1588,12 @@ static BlockJob *mirror_start_job(
|
||||
return NULL;
|
||||
}
|
||||
granularity = bdrv_dirty_bitmap_granularity(bitmap);
|
||||
+
|
||||
+ if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||
+ if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
} else if (granularity == 0) {
|
||||
granularity = bdrv_get_default_bitmap_granularity(target);
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
33
debian/patches/pve/0036-mirror-add-check-for-bitmap-mode-without-bitmap.patch
vendored
Normal file
33
debian/patches/pve/0036-mirror-add-check-for-bitmap-mode-without-bitmap.patch
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
From daec2f64e120a23a8d263f7d058bd84c48397bc8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
|
||||
Date: Mon, 17 Feb 2020 11:59:20 +0100
|
||||
Subject: [PATCH qemu 36/39] mirror: add check for bitmap-mode without bitmap
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
as one without the other does not make much sense with the current set
|
||||
of modes.
|
||||
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
---
|
||||
blockdev.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 08285b9e86..768a0b0fd4 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -3861,6 +3861,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
|
||||
return;
|
||||
}
|
||||
+ } else if (has_bitmap_mode) {
|
||||
+ error_setg(errp, "Cannot specify bitmap sync mode without a bitmap");
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (has_replaces) {
|
||||
--
|
||||
2.20.1
|
||||
|
45
debian/patches/pve/0037-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
vendored
Normal file
45
debian/patches/pve/0037-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
From 31ea5889c25012189aabe51157b32cfbe87a63be Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
|
||||
Date: Mon, 17 Feb 2020 10:43:22 +0100
|
||||
Subject: [PATCH qemu 37/39] mirror: switch to bdrv_dirty_bitmap_merge_internal
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
since sync_bitmap is busy at the point of merging, and we checked access
|
||||
beforehand.
|
||||
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
---
|
||||
block/mirror.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 40d174a625..d6aca2874e 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -735,8 +735,8 @@ static int mirror_exit_common(Job *job)
|
||||
job->ret == 0 && ret == 0)) {
|
||||
/* Success; synchronize copy back to sync. */
|
||||
bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL);
|
||||
- bdrv_merge_dirty_bitmap(s->sync_bitmap, s->dirty_bitmap,
|
||||
- NULL, &error_abort);
|
||||
+ bdrv_dirty_bitmap_merge_internal(s->sync_bitmap, s->dirty_bitmap,
|
||||
+ NULL, true);
|
||||
}
|
||||
}
|
||||
bdrv_release_dirty_bitmap(s->dirty_bitmap);
|
||||
@@ -1727,8 +1727,8 @@ static BlockJob *mirror_start_job(
|
||||
}
|
||||
|
||||
if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
|
||||
- bdrv_merge_dirty_bitmap(s->dirty_bitmap, s->sync_bitmap,
|
||||
- NULL, &local_err);
|
||||
+ bdrv_dirty_bitmap_merge_internal(s->dirty_bitmap, s->sync_bitmap,
|
||||
+ NULL, true);
|
||||
if (local_err) {
|
||||
goto fail;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
3447
debian/patches/pve/0038-iotests-add-test-for-bitmap-mirror.patch
vendored
Normal file
3447
debian/patches/pve/0038-iotests-add-test-for-bitmap-mirror.patch
vendored
Normal file
File diff suppressed because it is too large
Load Diff
275
debian/patches/pve/0039-mirror-move-some-checks-to-qmp.patch
vendored
Normal file
275
debian/patches/pve/0039-mirror-move-some-checks-to-qmp.patch
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
From 1beb9c370adff5e8c674d57e7a17672c0a8eaa2a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
|
||||
Date: Mon, 10 Feb 2020 10:15:16 +0100
|
||||
Subject: [PATCH qemu 39/39] mirror: move some checks to qmp
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
and assert the passing conditions in block/mirror.c. while incremental
|
||||
mode was never available for drive-mirror, it makes the interface more
|
||||
uniform w.r.t. backup block jobs.
|
||||
|
||||
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||
---
|
||||
block/mirror.c | 28 +++------------
|
||||
blockdev.c | 29 +++++++++++++++
|
||||
tests/qemu-iotests/284.out | 72 +++++++++++++++++++-------------------
|
||||
3 files changed, 70 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index d6aca2874e..7a3373fca7 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -1562,31 +1562,13 @@ static BlockJob *mirror_start_job(
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
- if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
|
||||
- error_setg(errp, "Sync mode '%s' not supported",
|
||||
- MirrorSyncMode_str(sync_mode));
|
||||
- return NULL;
|
||||
- } else if (sync_mode == MIRROR_SYNC_MODE_BITMAP) {
|
||||
- if (!bitmap) {
|
||||
- error_setg(errp, "Must provide a valid bitmap name for '%s'"
|
||||
- " sync mode",
|
||||
- MirrorSyncMode_str(sync_mode));
|
||||
- return NULL;
|
||||
- }
|
||||
- } else if (bitmap) {
|
||||
- error_setg(errp,
|
||||
- "sync mode '%s' is not compatible with bitmaps",
|
||||
- MirrorSyncMode_str(sync_mode));
|
||||
- return NULL;
|
||||
- }
|
||||
+ /* QMP interface protects us from these cases */
|
||||
+ assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
|
||||
+ assert((bitmap && sync_mode == MIRROR_SYNC_MODE_BITMAP) ||
|
||||
+ (!bitmap && sync_mode != MIRROR_SYNC_MODE_BITMAP));
|
||||
+ assert(!(bitmap && granularity));
|
||||
|
||||
if (bitmap) {
|
||||
- if (granularity) {
|
||||
- error_setg(errp, "granularity (%d)"
|
||||
- "cannot be specified when a bitmap is provided",
|
||||
- granularity);
|
||||
- return NULL;
|
||||
- }
|
||||
granularity = bdrv_dirty_bitmap_granularity(bitmap);
|
||||
|
||||
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 768a0b0fd4..4b196a2785 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -3840,7 +3840,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
|
||||
+ if ((sync == MIRROR_SYNC_MODE_BITMAP) ||
|
||||
+ (sync == MIRROR_SYNC_MODE_INCREMENTAL)) {
|
||||
+ /* done before desugaring 'incremental' to print the right message */
|
||||
+ if (!has_bitmap) {
|
||||
+ error_setg(errp, "Must provide a valid bitmap name for "
|
||||
+ "'%s' sync mode", MirrorSyncMode_str(sync));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sync == MIRROR_SYNC_MODE_INCREMENTAL) {
|
||||
+ if (has_bitmap_mode &&
|
||||
+ bitmap_mode != BITMAP_SYNC_MODE_ON_SUCCESS) {
|
||||
+ error_setg(errp, "Bitmap sync mode must be '%s' "
|
||||
+ "when using sync mode '%s'",
|
||||
+ BitmapSyncMode_str(BITMAP_SYNC_MODE_ON_SUCCESS),
|
||||
+ MirrorSyncMode_str(sync));
|
||||
+ return;
|
||||
+ }
|
||||
+ has_bitmap_mode = true;
|
||||
+ sync = MIRROR_SYNC_MODE_BITMAP;
|
||||
+ bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
if (has_bitmap) {
|
||||
+ if (sync != MIRROR_SYNC_MODE_BITMAP) {
|
||||
+ error_setg(errp, "Sync mode '%s' not supported with bitmap.",
|
||||
+ MirrorSyncMode_str(sync));
|
||||
+ return;
|
||||
+ }
|
||||
if (granularity) {
|
||||
error_setg(errp, "Granularity and bitmap cannot both be set");
|
||||
return;
|
||||
diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
|
||||
index 9b7408b6d6..06a2e29058 100644
|
||||
--- a/tests/qemu-iotests/284.out
|
||||
+++ b/tests/qemu-iotests/284.out
|
||||
@@ -2681,45 +2681,45 @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
|
||||
-- Sync mode incremental tests --
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'incremental' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'incremental' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'incremental' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'incremental' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
|
||||
|
||||
-- Sync mode bitmap tests --
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'bitmap' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'bitmap' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'bitmap' sync mode"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
|
||||
{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'bitmap' sync mode"}}
|
||||
@@ -2751,28 +2751,28 @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
|
||||
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
-- Sync mode top tests --
|
||||
|
||||
@@ -2786,28 +2786,28 @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
|
||||
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'full' not supported with bitmap."}}
|
||||
|
||||
-- Sync mode none tests --
|
||||
|
||||
@@ -2821,26 +2821,26 @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
|
||||
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
|
||||
-{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
|
||||
+{"error": {"class": "GenericError", "desc": "Sync mode 'none' not supported with bitmap."}}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
6
debian/patches/series
vendored
6
debian/patches/series
vendored
@ -30,6 +30,12 @@ pve/0030-PVE-Backup-add-backup-dump-block-driver.patch
|
||||
pve/0031-PVE-Backup-proxmox-backup-patches-for-qemu.patch
|
||||
pve/0032-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
|
||||
pve/0033-PVE-Backup-aquire-aio_context-before-calling-backup_.patch
|
||||
pve/0034-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
|
||||
pve/0035-drive-mirror-add-support-for-conditional-and-always-.patch
|
||||
pve/0036-mirror-add-check-for-bitmap-mode-without-bitmap.patch
|
||||
pve/0037-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
|
||||
pve/0038-iotests-add-test-for-bitmap-mirror.patch
|
||||
pve/0039-mirror-move-some-checks-to-qmp.patch
|
||||
security/0001-util-add-slirp_fmt-helpers.patch
|
||||
security/0002-tcp_emu-fix-unsafe-snprintf-usages.patch
|
||||
security/0003-ip_reass-Fix-use-after-free.patch
|
||||
|
Loading…
Reference in New Issue
Block a user