mirror of https://github.com/proxmox/mirror_qemu
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
commit
bdc408e91b
|
@ -1004,7 +1004,8 @@ fail:
|
||||||
return false;
|
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;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
Qcow2BitmapList *bm_list;
|
Qcow2BitmapList *bm_list;
|
||||||
|
@ -1012,6 +1013,10 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
|
||||||
GSList *ro_dirty_bitmaps = NULL;
|
GSList *ro_dirty_bitmaps = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (header_updated != NULL) {
|
||||||
|
*header_updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->nb_bitmaps == 0) {
|
if (s->nb_bitmaps == 0) {
|
||||||
/* No bitmaps - nothing to do */
|
/* No bitmaps - nothing to do */
|
||||||
return 0;
|
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");
|
error_setg_errno(errp, -ret, "Can't update bitmap directory");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (header_updated != NULL) {
|
||||||
|
*header_updated = true;
|
||||||
|
}
|
||||||
g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
|
g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,6 +1073,11 @@ out:
|
||||||
return ret;
|
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_data()
|
||||||
* Store bitmap to image, filling bitmap table accordingly.
|
* Store bitmap to image, filling bitmap table accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1480,7 +1480,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||||
s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
|
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;
|
update_header = false;
|
||||||
}
|
}
|
||||||
if (local_err != NULL) {
|
if (local_err != NULL) {
|
||||||
|
|
|
@ -671,6 +671,8 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
void **refcount_table,
|
void **refcount_table,
|
||||||
int64_t *refcount_table_size);
|
int64_t *refcount_table_size);
|
||||||
bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp);
|
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);
|
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
|
||||||
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
|
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
|
||||||
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
|
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#define VMDK4_FLAG_MARKER (1 << 17)
|
#define VMDK4_FLAG_MARKER (1 << 17)
|
||||||
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
|
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
|
||||||
|
|
||||||
|
#define VMDK_EXTENT_MAX_SECTORS (1ULL << 32)
|
||||||
|
|
||||||
#define VMDK_GTE_ZEROED 0x1
|
#define VMDK_GTE_ZEROED 0x1
|
||||||
|
|
||||||
/* VMDK internal error codes */
|
/* VMDK internal error codes */
|
||||||
|
@ -1250,6 +1252,10 @@ static int get_cluster_offset(BlockDriverState *bs,
|
||||||
return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
|
return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extent->next_cluster_sector >= VMDK_EXTENT_MAX_SECTORS) {
|
||||||
|
return VMDK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
cluster_sector = extent->next_cluster_sector;
|
cluster_sector = extent->next_cluster_sector;
|
||||||
extent->next_cluster_sector += extent->cluster_sectors;
|
extent->next_cluster_sector += extent->cluster_sectors;
|
||||||
|
|
||||||
|
|
|
@ -140,16 +140,14 @@ def inject_test_case(klass, name, method, *args, **kwargs):
|
||||||
mc = operator.methodcaller(method, *args, **kwargs)
|
mc = operator.methodcaller(method, *args, **kwargs)
|
||||||
setattr(klass, 'test_' + name, new.instancemethod(mc, None, klass))
|
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[0] else '_not_') + 'persistent_'
|
||||||
name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
|
name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
|
||||||
name += '_online' if cmb[2] else '_offline'
|
name += '_online' if cmb[2] else '_offline'
|
||||||
|
name += '_shared' if cmb[3] else '_nonshared'
|
||||||
# TODO fix shared-storage bitmap migration and enable cases for it
|
|
||||||
args = list(cmb) + [False]
|
|
||||||
|
|
||||||
inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
|
inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
|
||||||
*args)
|
*list(cmb))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
........
|
................
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
Ran 8 tests
|
Ran 16 tests
|
||||||
|
|
||||||
OK
|
OK
|
||||||
|
|
Loading…
Reference in New Issue