@@ -2733,6 +2733,57 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
aio_context_release(aio_context);
}
+void qmp_block_dirty_bitmap_create_successor(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;
+ }
+
+ bdrv_dirty_bitmap_create_successor(bs, bitmap, errp);
+
+ aio_context_release(aio_context);
+}
+
+void qmp_block_dirty_bitmap_abdicate(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;
+ }
+
+ bdrv_dirty_bitmap_abdicate(bs, bitmap, errp);
+
+ aio_context_release(aio_context);
+}
+
+void qmp_block_dirty_bitmap_reclaim(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;
+ }
+
+ bdrv_reclaim_dirty_bitmap(bs, bitmap, errp);
+
+ aio_context_release(aio_context);
+}
+
BlockDirtyRangeList *qmp_query_block_dirty_bitmap_ranges(const char *node,
const char *name, bool has_start, uint64_t start, bool has_count,
uint64_t count, uint32_t max_ranges, bool has_block_io, bool block_io,
@@ -1238,6 +1238,42 @@
'data': 'BlockDirtyBitmap' }
##
+# @block-dirty-bitmap-create-successor
+#
+# Interface to bdrv_dirty_bitmap_create_successor
+#
+# Returns: nothing on success
+#
+# Since 2.6
+##
+{ 'command': 'block-dirty-bitmap-create-successor',
+ 'data': 'BlockDirtyBitmap' }
+
+##
+# @block-dirty-bitmap-abdicate
+#
+# Interface to bdrv_dirty_bitmap_abdicate
+#
+# Returns: nothing on success
+#
+# Since 2.6
+##
+{ 'command': 'block-dirty-bitmap-abdicate',
+ 'data': 'BlockDirtyBitmap' }
+
+##
+# @block-dirty-bitmap-reclaim
+#
+# Interface to bdrv_reclaim_dirty_bitmap
+#
+# Returns: nothing on success
+#
+# Since 2.6
+##
+{ 'command': 'block-dirty-bitmap-reclaim',
+ 'data': 'BlockDirtyBitmap' }
+
+##
# @blockdev-mirror
#
# Start mirroring a block device's writes to a new destination.
@@ -1457,6 +1457,91 @@ Example:
EQMP
{
+ .name = "block-dirty-bitmap-create-successor",
+ .args_type = "node:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_create_successor,
+ },
+
+SQMP
+
+block-dirty-bitmap-create-successor
+------------------------
+Since 2.6
+
+Create a successor bitmap destined to replace this bitmap after an operation.
+Requires that the bitmap is not frozen and has no successor.
+
+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-create-successor",
+ "arguments": { "node": "drive0", "name": "bitmap0" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "block-dirty-bitmap-abdicate",
+ .args_type = "node:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_abdicate,
+ },
+
+SQMP
+
+block-dirty-bitmap-abdicate
+------------------------
+Since 2.6
+
+For a bitmap with a successor, yield our name to the successor, delete the old
+bitmap, and return a handle to the new bitmap.
+
+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-abdicate",
+ "arguments": { "node": "drive0", "name": "bitmap0" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "block-dirty-bitmap-reclaim",
+ .args_type = "node:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_reclaim,
+ },
+
+SQMP
+
+block-dirty-bitmap-reclaim
+------------------------
+Since 2.6
+
+In cases of failure where we can no longer safely delete the parent, we may
+wish to re-join the parent and child/successor. The merged parent will be
+un-frozen, but not explicitly re-enabled.
+
+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-reclaim",
+ "arguments": { "node": "drive0", "name": "bitmap0" } }
+<- { "return": {} }
+
+EQMP
+
+ {
.name = "query-block-dirty-bitmap-ranges",
.args_type = "node:B,name:s,start:i?,count:i?,max-ranges:i,"
"block-io:b?",
Add access to bdrv_dirty_bitmap_create_successor, bdrv_dirty_bitmap_abdicate, bdrv_reclaim_dirty_bitmap. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> --- blockdev.c | 51 +++++++++++++++++++++++++++++++ qapi/block-core.json | 36 ++++++++++++++++++++++ qmp-commands.hx | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+)