Skip to content

Commit

Permalink
qapi: support external bitmaps in block-dirty-bitmap-merge
Browse files Browse the repository at this point in the history
Add new optional parameter making possible to merge bitmaps from
different nodes. It is needed to maintain external snapshots during
incremental backup chain history.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 20190517152111.206494-2-vsementsov@virtuozzo.com
Signed-off-by: John Snow <jsnow@redhat.com>
  • Loading branch information
Vladimir Sementsov-Ogievskiy authored and jnsnow committed May 28, 2019
1 parent 592203e commit eff0829
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 23 deletions.
9 changes: 6 additions & 3 deletions block/dirty-bitmap.c
Expand Up @@ -816,10 +816,10 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
{
bool ret;

/* only bitmaps from one bds are supported */
assert(dest->mutex == src->mutex);

qemu_mutex_lock(dest->mutex);
if (src->mutex != dest->mutex) {
qemu_mutex_lock(src->mutex);
}

if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
goto out;
Expand All @@ -845,4 +845,7 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,

out:
qemu_mutex_unlock(dest->mutex);
if (src->mutex != dest->mutex) {
qemu_mutex_unlock(src->mutex);
}
}
50 changes: 33 additions & 17 deletions blockdev.c
Expand Up @@ -2112,11 +2112,10 @@ static void block_dirty_bitmap_disable_abort(BlkActionState *common)
}
}

static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
const char *target,
strList *bitmaps,
HBitmap **backup,
Error **errp);
static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(
const char *node, const char *target,
BlockDirtyBitmapMergeSourceList *bitmaps,
HBitmap **backup, Error **errp);

static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
Error **errp)
Expand Down Expand Up @@ -2965,15 +2964,14 @@ void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
bdrv_disable_dirty_bitmap(bitmap);
}

static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
const char *target,
strList *bitmaps,
HBitmap **backup,
Error **errp)
static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(
const char *node, const char *target,
BlockDirtyBitmapMergeSourceList *bitmaps,
HBitmap **backup, Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *dst, *src, *anon;
strList *lst;
BlockDirtyBitmapMergeSourceList *lst;
Error *local_err = NULL;

dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
Expand All @@ -2988,11 +2986,28 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
}

for (lst = bitmaps; lst; lst = lst->next) {
src = bdrv_find_dirty_bitmap(bs, lst->value);
if (!src) {
error_setg(errp, "Dirty bitmap '%s' not found", lst->value);
dst = NULL;
goto out;
switch (lst->value->type) {
const char *name, *node;
case QTYPE_QSTRING:
name = lst->value->u.local;
src = bdrv_find_dirty_bitmap(bs, name);
if (!src) {
error_setg(errp, "Dirty bitmap '%s' not found", name);
dst = NULL;
goto out;
}
break;
case QTYPE_QDICT:
node = lst->value->u.external.node;
name = lst->value->u.external.name;
src = block_dirty_bitmap_lookup(node, name, NULL, errp);
if (!src) {
dst = NULL;
goto out;
}
break;
default:
abort();
}

bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
Expand All @@ -3012,7 +3027,8 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
}

void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
strList *bitmaps, Error **errp)
BlockDirtyBitmapMergeSourceList *bitmaps,
Error **errp)
{
do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
}
Expand Down
22 changes: 19 additions & 3 deletions qapi/block-core.json
Expand Up @@ -2003,19 +2003,35 @@
'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32',
'*persistent': 'bool', '*autoload': 'bool', '*disabled': 'bool' } }

##
# @BlockDirtyBitmapMergeSource:
#
# @local: name of the bitmap, attached to the same node as target bitmap.
#
# @external: bitmap with specified node
#
# Since: 4.1
##
{ 'alternate': 'BlockDirtyBitmapMergeSource',
'data': { 'local': 'str',
'external': 'BlockDirtyBitmap' } }

##
# @BlockDirtyBitmapMerge:
#
# @node: name of device/node which the bitmap is tracking
# @node: name of device/node which the @target bitmap is tracking
#
# @target: name of the destination dirty bitmap
#
# @bitmaps: name(s) of the source dirty bitmap(s)
# @bitmaps: name(s) of the source dirty bitmap(s) at @node and/or fully
# specifed BlockDirtyBitmap elements. The latter are supported
# since 4.1.
#
# Since: 4.0
##
{ 'struct': 'BlockDirtyBitmapMerge',
'data': { 'node': 'str', 'target': 'str', 'bitmaps': ['str'] } }
'data': { 'node': 'str', 'target': 'str',
'bitmaps': ['BlockDirtyBitmapMergeSource'] } }

##
# @block-dirty-bitmap-add:
Expand Down

0 comments on commit eff0829

Please sign in to comment.