qmp: add block-dirty-bitmap-clear
Add bdrv_clear_dirty_bitmap and a matching QMP command, qmp_block_dirty_bitmap_clear that enables a user to reset the bitmap attached to a drive. This allows us to reset a bitmap in the event of a full drive backup. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 1429314609-29776-12-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
d58d845397
commit
e74e6b78e6
8
block.c
8
block.c
@ -63,6 +63,7 @@
|
||||
struct BdrvDirtyBitmap {
|
||||
HBitmap *bitmap;
|
||||
BdrvDirtyBitmap *successor;
|
||||
int64_t size;
|
||||
char *name;
|
||||
bool disabled;
|
||||
QLIST_ENTRY(BdrvDirtyBitmap) list;
|
||||
@ -5557,6 +5558,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
|
||||
}
|
||||
bitmap = g_new0(BdrvDirtyBitmap, 1);
|
||||
bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
|
||||
bitmap->size = bitmap_size;
|
||||
bitmap->name = g_strdup(name);
|
||||
bitmap->disabled = false;
|
||||
QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
|
||||
@ -5759,6 +5761,12 @@ void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
|
||||
hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
|
||||
}
|
||||
|
||||
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap)
|
||||
{
|
||||
assert(bdrv_dirty_bitmap_enabled(bitmap));
|
||||
hbitmap_reset(bitmap->bitmap, 0, bitmap->size);
|
||||
}
|
||||
|
||||
static void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
|
||||
int nr_sectors)
|
||||
{
|
||||
|
34
blockdev.c
34
blockdev.c
@ -2079,6 +2079,40 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely clear a bitmap, for the purposes of synchronizing a bitmap
|
||||
* immediately after a full backup operation.
|
||||
*/
|
||||
void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BdrvDirtyBitmap *bitmap;
|
||||
BlockDriverState *bs;
|
||||
|
||||
bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
|
||||
if (!bitmap || !bs) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bdrv_dirty_bitmap_frozen(bitmap)) {
|
||||
error_setg(errp,
|
||||
"Bitmap '%s' is currently frozen and cannot be modified",
|
||||
name);
|
||||
goto out;
|
||||
} else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
|
||||
error_setg(errp,
|
||||
"Bitmap '%s' is currently disabled and cannot be cleared",
|
||||
name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_clear_dirty_bitmap(bitmap);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
{
|
||||
const char *id = qdict_get_str(qdict, "id");
|
||||
|
@ -479,6 +479,7 @@ void bdrv_set_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
|
||||
int64_t cur_sector, int nr_sectors);
|
||||
void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
|
||||
int64_t cur_sector, int nr_sectors);
|
||||
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
||||
void bdrv_dirty_iter_init(BlockDriverState *bs,
|
||||
BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
|
||||
void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
|
||||
|
@ -1021,6 +1021,20 @@
|
||||
{ 'command': 'block-dirty-bitmap-remove',
|
||||
'data': 'BlockDirtyBitmap' }
|
||||
|
||||
##
|
||||
# @block-dirty-bitmap-clear
|
||||
#
|
||||
# Clear (reset) a dirty bitmap on the device
|
||||
#
|
||||
# Returns: nothing on success
|
||||
# If @node is not a valid block device, DeviceNotFound
|
||||
# If @name is not found, GenericError with an explanation
|
||||
#
|
||||
# Since 2.4
|
||||
##
|
||||
{ 'command': 'block-dirty-bitmap-clear',
|
||||
'data': 'BlockDirtyBitmap' }
|
||||
|
||||
##
|
||||
# @block_set_io_throttle:
|
||||
#
|
||||
|
@ -1361,6 +1361,35 @@ Example:
|
||||
"name": "bitmap0" } }
|
||||
<- { "return": {} }
|
||||
|
||||
EQMP
|
||||
|
||||
{
|
||||
.name = "block-dirty-bitmap-clear",
|
||||
.args_type = "node:B,name:s",
|
||||
.mhandler.cmd_new = qmp_marshal_input_block_dirty_bitmap_clear,
|
||||
},
|
||||
|
||||
SQMP
|
||||
|
||||
block-dirty-bitmap-clear
|
||||
------------------------
|
||||
Since 2.4
|
||||
|
||||
Reset the dirty bitmap associated with a node so that an incremental backup
|
||||
from this point in time forward will only backup clusters modified after this
|
||||
clear operation.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "node": device/node on which to remove dirty bitmap (json-string)
|
||||
- "name": name of the dirty bitmap to remove (json-string)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "block-dirty-bitmap-clear", "arguments": { "node": "drive0",
|
||||
"name": "bitmap0" } }
|
||||
<- { "return": {} }
|
||||
|
||||
EQMP
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user