Commit e74e6b78 authored by John Snow's avatar John Snow Committed by Kevin Wolf
Browse files

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: default avatarJohn Snow <jsnow@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Message-id: 1429314609-29776-12-git-send-email-jsnow@redhat.com
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent d58d8453
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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");
+1 −0
Original line number Diff line number Diff line
@@ -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);
+14 −0
Original line number Diff line number Diff line
@@ -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:
#
+29 −0
Original line number Diff line number Diff line
@@ -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

    {