From e1a7b82bc7f0dc8f65c9bf07acbcdca1fb08bb17 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 20 Nov 2018 18:18:16 +0000 Subject: [PATCH 22/35] block/dirty-bitmaps: add user_locked status checker RH-Author: John Snow Message-id: <20181120181828.15132-13-jsnow@redhat.com> Patchwork-id: 83056 O-Subject: [RHEL8/rhel qemu-kvm PATCH 12/24] block/dirty-bitmaps: add user_locked status checker Bugzilla: 1518989 RH-Acked-by: Laurent Vivier RH-Acked-by: Max Reitz RH-Acked-by: Stefan Hajnoczi Instead of both frozen and qmp_locked checks, wrap it into one check. frozen implies the bitmap is split in two (for backup), and shouldn't be modified. qmp_locked implies it's being used by another operation, like being exported over NBD. In both cases it means we shouldn't allow the user to modify it in any meaningful way. Replace any usages where we check both frozen and qmp_locked with the new check. Signed-off-by: John Snow Reviewed-by: Eric Blake Message-id: 20181002230218.13949-2-jsnow@redhat.com [w/edits Suggested-By: Vladimir Sementsov-Ogievskiy ] Signed-off-by: John Snow (cherry picked from commit 993edc0ce0c6f44deb8272a7a857e419417f5f84) Signed-off-by: John Snow Signed-off-by: Danilo C. L. de Paula --- block/dirty-bitmap.c | 6 ++++++ blockdev.c | 29 ++++++++--------------------- include/block/dirty-bitmap.h | 1 + migration/block-dirty-bitmap.c | 10 ++-------- 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 8ac933c..9603cdd 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -176,6 +176,12 @@ bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) return bitmap->successor; } +/* Both conditions disallow user-modification via QMP. */ +bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) { + return bdrv_dirty_bitmap_frozen(bitmap) || + bdrv_dirty_bitmap_qmp_locked(bitmap); +} + void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked) { qemu_mutex_lock(bitmap->mutex); diff --git a/blockdev.c b/blockdev.c index d2e7e5a..5cdb608 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2119,11 +2119,8 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_frozen(state->bitmap)) { - error_setg(errp, "Cannot modify a frozen bitmap"); - return; - } else if (bdrv_dirty_bitmap_qmp_locked(state->bitmap)) { - error_setg(errp, "Cannot modify a locked bitmap"); + if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { + error_setg(errp, "Cannot modify a bitmap in use by another operation"); return; } else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) { error_setg(errp, "Cannot clear a disabled bitmap"); @@ -2992,15 +2989,10 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_frozen(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently frozen and cannot be removed", - name); - return; - } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { + if (bdrv_dirty_bitmap_user_locked(bitmap)) { error_setg(errp, - "Bitmap '%s' is currently locked and cannot be removed", - name); + "Bitmap '%s' is currently in use by another operation and" + " cannot be removed", name); return; } @@ -3030,15 +3022,10 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_frozen(bitmap)) { + if (bdrv_dirty_bitmap_user_locked(bitmap)) { error_setg(errp, - "Bitmap '%s' is currently frozen and cannot be modified", - name); - return; - } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently locked and cannot be modified", - name); + "Bitmap '%s' is currently in use by another operation" + " and cannot be cleared", name); return; } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { error_setg(errp, diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index 201ff7f..1463943 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -94,6 +94,7 @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap); +bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap); bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index fefbc6a..47251af 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -301,14 +301,8 @@ static int init_dirty_bitmap_migration(void) goto fail; } - if (bdrv_dirty_bitmap_frozen(bitmap)) { - error_report("Can't migrate frozen dirty bitmap: '%s", - bdrv_dirty_bitmap_name(bitmap)); - goto fail; - } - - if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { - error_report("Can't migrate locked dirty bitmap: '%s", + if (bdrv_dirty_bitmap_user_locked(bitmap)) { + error_report("Can't migrate a bitmap that is in use by another operation: '%s'", bdrv_dirty_bitmap_name(bitmap)); goto fail; } -- 1.8.3.1