Skip to content

Commit

Permalink
qmp: add block-dirty-bitmap-clear
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Max Reitz <[email protected]>
Reviewed-by: Stefan Hajnoczi <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
Message-id: [email protected]
Signed-off-by: Stefan Hajnoczi <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>
  • Loading branch information
jnsnow authored and kevmw committed Apr 28, 2015
1 parent d58d845 commit e74e6b7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 0 deletions.
8 changes: 8 additions & 0 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
struct BdrvDirtyBitmap {
HBitmap *bitmap;
BdrvDirtyBitmap *successor;
int64_t size;
char *name;
bool disabled;
QLIST_ENTRY(BdrvDirtyBitmap) list;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand Down
34 changes: 34 additions & 0 deletions blockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions include/block/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions qapi/block-core.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:
#
Expand Down
29 changes: 29 additions & 0 deletions qmp-commands.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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

{
Expand Down

0 comments on commit e74e6b7

Please sign in to comment.