diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-03-16 14:15:18 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-03-16 14:15:18 +0000 |
commit | 9cc7d0cf6a6dc300db4db25421eff782623d6b18 (patch) | |
tree | bde6a86755607d479a93e1439cf6ed21feccbed5 /block | |
parent | 475fe4576f11e9389a188bd5698ae05458c397c2 (diff) | |
parent | ac8bd439bb7b5dffeb5ff8a17317ca2b192044b6 (diff) | |
download | qemu-9cc7d0cf6a6dc300db4db25421eff782623d6b18.zip qemu-9cc7d0cf6a6dc300db4db25421eff782623d6b18.tar.gz qemu-9cc7d0cf6a6dc300db4db25421eff782623d6b18.tar.bz2 |
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging
# gpg: Signature made Tue 13 Mar 2018 21:11:43 GMT
# gpg: using RSA key 7DEF8106AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB
# Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E
* remotes/jnsnow/tags/bitmaps-pull-request:
iotests: add dirty bitmap postcopy test
iotests: add dirty bitmap migration test
migration: add postcopy migration of dirty bitmaps
migration: allow qmp command migrate-start-postcopy for any postcopy
migration: add is_active_iterate handler
migration/qemu-file: add qemu_put_counted_string()
migration: include migrate_dirty_bitmaps in migrate_postcopy
qapi: add dirty-bitmaps migration capability
migration: introduce postcopy-only pending
dirty-bitmap: add locked state
block/dirty-bitmap: add _locked version of bdrv_reclaim_dirty_bitmap
block/dirty-bitmap: fix locking in bdrv_reclaim_dirty_bitmap
block/dirty-bitmap: add bdrv_dirty_bitmap_enable_successor()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block')
-rw-r--r-- | block/dirty-bitmap.c | 123 |
1 files changed, 88 insertions, 35 deletions
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 909f051..9671594 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -40,6 +40,8 @@ struct BdrvDirtyBitmap { QemuMutex *mutex; HBitmap *bitmap; /* Dirty bitmap implementation */ HBitmap *meta; /* Meta dirty bitmap */ + bool qmp_locked; /* Bitmap is locked, it can't be modified + through QMP */ BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */ char *name; /* Optional non-empty unique ID */ int64_t size; /* Size of the bitmap, in bytes */ @@ -183,6 +185,18 @@ bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) return bitmap->successor; } +void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked) +{ + qemu_mutex_lock(bitmap->mutex); + bitmap->qmp_locked = qmp_locked; + qemu_mutex_unlock(bitmap->mutex); +} + +bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap) +{ + return bitmap->qmp_locked; +} + /* Called with BQL taken. */ bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap) { @@ -194,6 +208,8 @@ DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap) { if (bdrv_dirty_bitmap_frozen(bitmap)) { return DIRTY_BITMAP_STATUS_FROZEN; + } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { + return DIRTY_BITMAP_STATUS_LOCKED; } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { return DIRTY_BITMAP_STATUS_DISABLED; } else { @@ -234,6 +250,59 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs, return 0; } +/* Called with BQL taken. */ +void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap) +{ + qemu_mutex_lock(bitmap->mutex); + bdrv_enable_dirty_bitmap(bitmap->successor); + qemu_mutex_unlock(bitmap->mutex); +} + +/* Called within bdrv_dirty_bitmap_lock..unlock */ +static void bdrv_do_release_matching_dirty_bitmap_locked( + BlockDriverState *bs, BdrvDirtyBitmap *bitmap, + bool (*cond)(BdrvDirtyBitmap *bitmap)) +{ + BdrvDirtyBitmap *bm, *next; + + QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { + if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) { + assert(!bm->active_iterators); + assert(!bdrv_dirty_bitmap_frozen(bm)); + assert(!bm->meta); + QLIST_REMOVE(bm, list); + hbitmap_free(bm->bitmap); + g_free(bm->name); + g_free(bm); + + if (bitmap) { + return; + } + } + } + + if (bitmap) { + abort(); + } +} + +/* Called with BQL taken. */ +static void bdrv_do_release_matching_dirty_bitmap( + BlockDriverState *bs, BdrvDirtyBitmap *bitmap, + bool (*cond)(BdrvDirtyBitmap *bitmap)) +{ + bdrv_dirty_bitmaps_lock(bs); + bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, cond); + bdrv_dirty_bitmaps_unlock(bs); +} + +/* Called within bdrv_dirty_bitmap_lock..unlock */ +static void bdrv_release_dirty_bitmap_locked(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap) +{ + bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, NULL); +} + /** * For a bitmap with a successor, yield our name to the successor, * delete the old bitmap, and return a handle to the new bitmap. @@ -267,11 +336,11 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, * In cases of failure where we can no longer safely delete the parent, * we may wish to re-join the parent and child/successor. * The merged parent will be un-frozen, but not explicitly re-enabled. - * Called with BQL taken. + * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */ -BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, - BdrvDirtyBitmap *parent, - Error **errp) +BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs, + BdrvDirtyBitmap *parent, + Error **errp) { BdrvDirtyBitmap *successor = parent->successor; @@ -284,12 +353,26 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, error_setg(errp, "Merging of parent and successor bitmap failed"); return NULL; } - bdrv_release_dirty_bitmap(bs, successor); + bdrv_release_dirty_bitmap_locked(bs, successor); parent->successor = NULL; return parent; } +/* Called with BQL taken. */ +BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, + BdrvDirtyBitmap *parent, + Error **errp) +{ + BdrvDirtyBitmap *ret; + + qemu_mutex_lock(parent->mutex); + ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp); + qemu_mutex_unlock(parent->mutex); + + return ret; +} + /** * Truncates _all_ bitmaps attached to a BDS. * Called with BQL taken. @@ -314,36 +397,6 @@ static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap) } /* Called with BQL taken. */ -static void bdrv_do_release_matching_dirty_bitmap( - BlockDriverState *bs, BdrvDirtyBitmap *bitmap, - bool (*cond)(BdrvDirtyBitmap *bitmap)) -{ - BdrvDirtyBitmap *bm, *next; - bdrv_dirty_bitmaps_lock(bs); - QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { - if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) { - assert(!bm->active_iterators); - assert(!bdrv_dirty_bitmap_frozen(bm)); - assert(!bm->meta); - QLIST_REMOVE(bm, list); - hbitmap_free(bm->bitmap); - g_free(bm->name); - g_free(bm); - - if (bitmap) { - goto out; - } - } - } - if (bitmap) { - abort(); - } - -out: - bdrv_dirty_bitmaps_unlock(bs); -} - -/* Called with BQL taken. */ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) { bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL); |