aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>2018-03-20 20:05:19 +0300
committerMax Reitz <mreitz@redhat.com>2018-03-26 21:17:24 +0200
commit2d949dfcefcf12831620549cea8f4e537f9de5f2 (patch)
treebcbc33d306132597e48c387b9b8e05c992e1392d
parentb1336cc2ec87a6593e1167af6e5b2cbd3d31acac (diff)
qcow2: fix bitmaps loading when bitmaps already exist
On reopen with existing bitmaps, instead of loading bitmaps, lets reopen them if needed. This also fixes bitmaps migration through shared storage. Consider the case. Persistent bitmaps are stored on bdrv_inactivate. Then, on destination process_incoming_migration_bh() calls bdrv_invalidate_cache_all() which leads to qcow2_load_autoloading_dirty_bitmaps() which fails if bitmaps are already loaded on destination start. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-id: 20180320170521.32152-3-vsementsov@virtuozzo.com Signed-off-by: Max Reitz <mreitz@redhat.com>
-rw-r--r--block/qcow2.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index cf4f3becae..486f3e83b7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1480,7 +1480,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
}
- if (qcow2_load_dirty_bitmaps(bs, &local_err)) {
+ if (bdrv_dirty_bitmap_next(bs, NULL)) {
+ /* It's some kind of reopen with already existing dirty bitmaps. There
+ * are no known cases where we need loading bitmaps in such situation,
+ * so it's safer don't load them.
+ *
+ * Moreover, if we have some readonly bitmaps and we are reopening for
+ * rw we should reopen bitmaps correspondingly.
+ */
+ if (bdrv_has_readonly_bitmaps(bs) &&
+ !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE))
+ {
+ bool header_updated = false;
+ qcow2_reopen_bitmaps_rw_hint(bs, &header_updated, &local_err);
+ update_header = update_header && !header_updated;
+ }
+ } else if (qcow2_load_dirty_bitmaps(bs, &local_err)) {
update_header = false;
}
if (local_err != NULL) {