A fix for dirty bitmap migration through shared storage, and a VMDK

patch keeping us from creating too large extents.
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJauVVBAAoJEPQH2wBh1c9AGtYIAJ1ojl6+guKQHjtzv9W8ch50
 2tzH9/lFkhq/Tyay8MCcq1dWQr23tKqusxi6fDHVdc8XIx6fDuPFzWxUQwwLvS81
 9CA6Qs2NngkiAs89ZZ0Sc9aj+LzFbKvXDXPYd4FFeLVVzD0CA4qghH5THrrH6LRm
 4DoRUK1QejrOC0v2zCRQvEN6RlI6WFGCf9YiYKkdrvswnjtLgOobCt7TvC9Nade2
 smGyxtDENkV6bAZgQgxMAlf88GCyKslb4Fu6U+sfKMDejWmlYEREbBsQc+/Gp6Af
 R6ZeiXEJ+KUF34RktPTmhJlUbzRc4Mw0Ij7Abrfhtpre9hifIp62XSrM8sasgLo=
 =k+ly
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2018-03-26' into staging

A fix for dirty bitmap migration through shared storage, and a VMDK
patch keeping us from creating too large extents.

# gpg: Signature made Mon 26 Mar 2018 21:17:05 BST
# gpg:                using RSA key F407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2018-03-26:
  vmdk: return ERROR when cluster sector is larger than vmdk limitation
  iotests: enable shared migration cases in 169
  qcow2: fix bitmaps loading when bitmaps already exist
  qcow2-bitmap: add qcow2_reopen_bitmaps_rw_hint()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2018-03-27 14:11:30 +01:00
commit bdc408e91b
6 changed files with 43 additions and 9 deletions

View File

@ -1004,7 +1004,8 @@ fail:
return false;
}
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
Qcow2BitmapList *bm_list;
@ -1012,6 +1013,10 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
GSList *ro_dirty_bitmaps = NULL;
int ret = 0;
if (header_updated != NULL) {
*header_updated = false;
}
if (s->nb_bitmaps == 0) {
/* No bitmaps - nothing to do */
return 0;
@ -1055,6 +1060,9 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
error_setg_errno(errp, -ret, "Can't update bitmap directory");
goto out;
}
if (header_updated != NULL) {
*header_updated = true;
}
g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
}
@ -1065,6 +1073,11 @@ out:
return ret;
}
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
{
return qcow2_reopen_bitmaps_rw_hint(bs, NULL, errp);
}
/* store_bitmap_data()
* Store bitmap to image, filling bitmap table accordingly.
*/

View File

@ -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) {

View File

@ -671,6 +671,8 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
void **refcount_table,
int64_t *refcount_table_size);
bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp);
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
Error **errp);
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);

View File

@ -47,6 +47,8 @@
#define VMDK4_FLAG_MARKER (1 << 17)
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
#define VMDK_EXTENT_MAX_SECTORS (1ULL << 32)
#define VMDK_GTE_ZEROED 0x1
/* VMDK internal error codes */
@ -1250,6 +1252,10 @@ static int get_cluster_offset(BlockDriverState *bs,
return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
}
if (extent->next_cluster_sector >= VMDK_EXTENT_MAX_SECTORS) {
return VMDK_ERROR;
}
cluster_sector = extent->next_cluster_sector;
extent->next_cluster_sector += extent->cluster_sectors;

View File

@ -140,16 +140,14 @@ def inject_test_case(klass, name, method, *args, **kwargs):
mc = operator.methodcaller(method, *args, **kwargs)
setattr(klass, 'test_' + name, new.instancemethod(mc, None, klass))
for cmb in list(itertools.product((True, False), repeat=3)):
for cmb in list(itertools.product((True, False), repeat=4)):
name = ('_' if cmb[0] else '_not_') + 'persistent_'
name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
name += '_online' if cmb[2] else '_offline'
# TODO fix shared-storage bitmap migration and enable cases for it
args = list(cmb) + [False]
name += '_shared' if cmb[3] else '_nonshared'
inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
*args)
*list(cmb))
if __name__ == '__main__':

View File

@ -1,5 +1,5 @@
........
................
----------------------------------------------------------------------
Ran 8 tests
Ran 16 tests
OK