block/dirty-bitmaps: add inconsistent bit

Add an inconsistent bit to dirty-bitmaps that allows us to report a bitmap as
persistent but potentially inconsistent, i.e. if we find bitmaps on a qcow2
that have been marked as "in use".

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190301191545.8728-2-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
This commit is contained in:
John Snow 2019-03-12 12:05:49 -04:00
parent c61b198b63
commit b0f455599d
3 changed files with 31 additions and 4 deletions

View File

@ -46,6 +46,9 @@ struct BdrvDirtyBitmap {
and this bitmap must remain unchanged while and this bitmap must remain unchanged while
this flag is set. */ this flag is set. */
bool persistent; /* bitmap must be saved to owner disk image */ bool persistent; /* bitmap must be saved to owner disk image */
bool inconsistent; /* bitmap is persistent, but inconsistent.
It cannot be used at all in any way, except
a QMP user can remove it. */
bool migration; /* Bitmap is selected for migration, it should bool migration; /* Bitmap is selected for migration, it should
not be stored on the next inactivation not be stored on the next inactivation
(persistent flag doesn't matter until next (persistent flag doesn't matter until next
@ -465,6 +468,8 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
info->recording = bdrv_dirty_bitmap_recording(bm); info->recording = bdrv_dirty_bitmap_recording(bm);
info->busy = bdrv_dirty_bitmap_busy(bm); info->busy = bdrv_dirty_bitmap_busy(bm);
info->persistent = bm->persistent; info->persistent = bm->persistent;
info->has_inconsistent = bm->inconsistent;
info->inconsistent = bm->inconsistent;
entry->value = info; entry->value = info;
*plist = entry; *plist = entry;
plist = &entry->next; plist = &entry->next;
@ -712,6 +717,16 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
qemu_mutex_unlock(bitmap->mutex); qemu_mutex_unlock(bitmap->mutex);
} }
/* Called with BQL taken. */
void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
{
qemu_mutex_lock(bitmap->mutex);
assert(bitmap->persistent == true);
bitmap->inconsistent = true;
bitmap->disabled = true;
qemu_mutex_unlock(bitmap->mutex);
}
/* Called with BQL taken. */ /* Called with BQL taken. */
void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration) void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration)
{ {
@ -725,6 +740,11 @@ bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
return bitmap->persistent && !bitmap->migration; return bitmap->persistent && !bitmap->migration;
} }
bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
{
return bitmap->inconsistent;
}
bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
{ {
BdrvDirtyBitmap *bm; BdrvDirtyBitmap *bm;

View File

@ -68,6 +68,7 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value);
void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
bool persistent); bool persistent);
void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap);
void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy); void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy);
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
HBitmap **backup, Error **errp); HBitmap **backup, Error **errp);
@ -91,6 +92,7 @@ bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap);
bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap);
bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap);
bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap);
bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs);
BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,

View File

@ -476,15 +476,20 @@
# and cannot be modified via QMP or used by another operation. # and cannot be modified via QMP or used by another operation.
# Replaces `locked` and `frozen` statuses. (since 4.0) # Replaces `locked` and `frozen` statuses. (since 4.0)
# #
# @persistent: true if the bitmap will eventually be flushed to persistent # @persistent: true if the bitmap was stored on disk, is scheduled to be stored
# storage (since 4.0) # on disk, or both. (since 4.0)
#
# @inconsistent: true if this is a persistent bitmap that was improperly
# stored. Implies @persistent to be true; @recording and
# @busy to be false. This bitmap cannot be used. To remove
# it, use @block-dirty-bitmap-remove. (Since 4.0)
# #
# Since: 1.3 # Since: 1.3
## ##
{ 'struct': 'BlockDirtyInfo', { 'struct': 'BlockDirtyInfo',
'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32', 'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
'recording': 'bool', 'busy': 'bool', 'recording': 'bool', 'busy': 'bool', 'status': 'DirtyBitmapStatus',
'status': 'DirtyBitmapStatus', 'persistent': 'bool' } } 'persistent': 'bool', '*inconsistent': 'bool' } }
## ##
# @Qcow2BitmapInfoFlags: # @Qcow2BitmapInfoFlags: