Blame SOURCES/kvm-blockdev-n-ary-bitmap-merge.patch

7711c0
From 80ea6f080180cd5aea1603405948d164442dd8d1 Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Wed, 20 Mar 2019 16:16:16 +0100
7711c0
Subject: [PATCH 018/163] blockdev: n-ary bitmap merge
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190320161631.14841-5-jsnow@redhat.com>
7711c0
Patchwork-id: 84948
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 04/19] blockdev: n-ary bitmap merge
7711c0
Bugzilla: 1668956
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7711c0
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
7711c0
Especially outside of transactions, it is helpful to provide
7711c0
all-or-nothing semantics for bitmap merges. This facilitates
7711c0
the coalescing of multiple bitmaps into a single target for
7711c0
the "checkpoint" interpretation when assembling bitmaps that
7711c0
represent arbitrary points in time from component bitmaps.
7711c0
7711c0
This is an incompatible change from the preliminary version
7711c0
of the API.
7711c0
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Reviewed-by: Eric Blake <eblake@redhat.com>
7711c0
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7711c0
Message-Id: <20181221093529.23855-4-jsnow@redhat.com>
7711c0
Signed-off-by: Eric Blake <eblake@redhat.com>
7711c0
(cherry picked from commit 360d4e4e9a501d92fb8866ac307d33a25f70c6d1)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 blockdev.c           | 75 +++++++++++++++++++++++++++++++++++-----------------
7711c0
 qapi/block-core.json | 22 +++++++--------
7711c0
 2 files changed, 62 insertions(+), 35 deletions(-)
7711c0
7711c0
diff --git a/blockdev.c b/blockdev.c
7711c0
index c9bda43..3755936 100644
7711c0
--- a/blockdev.c
7711c0
+++ b/blockdev.c
7711c0
@@ -2272,33 +2272,28 @@ static void block_dirty_bitmap_disable_abort(BlkActionState *common)
7711c0
     }
7711c0
 }
7711c0
 
7711c0
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
7711c0
+                                                    const char *target,
7711c0
+                                                    strList *bitmaps,
7711c0
+                                                    HBitmap **backup,
7711c0
+                                                    Error **errp);
7711c0
+
7711c0
 static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
7711c0
                                              Error **errp)
7711c0
 {
7711c0
     BlockDirtyBitmapMerge *action;
7711c0
     BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
7711c0
                                              common, common);
7711c0
-    BdrvDirtyBitmap *merge_source;
7711c0
 
7711c0
     if (action_check_completion_mode(common, errp) < 0) {
7711c0
         return;
7711c0
     }
7711c0
 
7711c0
     action = common->action->u.x_block_dirty_bitmap_merge.data;
7711c0
-    state->bitmap = block_dirty_bitmap_lookup(action->node,
7711c0
-                                              action->dst_name,
7711c0
-                                              &state->bs,
7711c0
-                                              errp);
7711c0
-    if (!state->bitmap) {
7711c0
-        return;
7711c0
-    }
7711c0
 
7711c0
-    merge_source = bdrv_find_dirty_bitmap(state->bs, action->src_name);
7711c0
-    if (!merge_source) {
7711c0
-        return;
7711c0
-    }
7711c0
-
7711c0
-    bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, errp);
7711c0
+    state->bitmap = do_block_dirty_bitmap_merge(action->node, action->target,
7711c0
+                                                action->bitmaps, &state->backup,
7711c0
+                                                errp);
7711c0
 }
7711c0
 
7711c0
 static void abort_prepare(BlkActionState *common, Error **errp)
7711c0
@@ -3130,24 +3125,56 @@ void qmp_x_block_dirty_bitmap_disable(const char *node, const char *name,
7711c0
     bdrv_disable_dirty_bitmap(bitmap);
7711c0
 }
7711c0
 
7711c0
-void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
7711c0
-                                    const char *src_name, Error **errp)
7711c0
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
7711c0
+                                                    const char *target,
7711c0
+                                                    strList *bitmaps,
7711c0
+                                                    HBitmap **backup,
7711c0
+                                                    Error **errp)
7711c0
 {
7711c0
     BlockDriverState *bs;
7711c0
-    BdrvDirtyBitmap *dst, *src;
7711c0
+    BdrvDirtyBitmap *dst, *src, *anon;
7711c0
+    strList *lst;
7711c0
+    Error *local_err = NULL;
7711c0
 
7711c0
-    dst = block_dirty_bitmap_lookup(node, dst_name, &bs, errp);
7711c0
+    dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
7711c0
     if (!dst) {
7711c0
-        return;
7711c0
+        return NULL;
7711c0
     }
7711c0
 
7711c0
-    src = bdrv_find_dirty_bitmap(bs, src_name);
7711c0
-    if (!src) {
7711c0
-        error_setg(errp, "Dirty bitmap '%s' not found", src_name);
7711c0
-        return;
7711c0
+    anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
7711c0
+                                    NULL, errp);
7711c0
+    if (!anon) {
7711c0
+        return NULL;
7711c0
+    }
7711c0
+
7711c0
+    for (lst = bitmaps; lst; lst = lst->next) {
7711c0
+        src = bdrv_find_dirty_bitmap(bs, lst->value);
7711c0
+        if (!src) {
7711c0
+            error_setg(errp, "Dirty bitmap '%s' not found", lst->value);
7711c0
+            dst = NULL;
7711c0
+            goto out;
7711c0
+        }
7711c0
+
7711c0
+        bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
7711c0
+        if (local_err) {
7711c0
+            error_propagate(errp, local_err);
7711c0
+            dst = NULL;
7711c0
+            goto out;
7711c0
+        }
7711c0
     }
7711c0
 
7711c0
-    bdrv_merge_dirty_bitmap(dst, src, NULL, errp);
7711c0
+    /* Merge into dst; dst is unchanged on failure. */
7711c0
+    bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
7711c0
+
7711c0
+ out:
7711c0
+    bdrv_release_dirty_bitmap(bs, anon);
7711c0
+    return dst;
7711c0
+}
7711c0
+
7711c0
+void qmp_x_block_dirty_bitmap_merge(const char *node, const char *target,
7711c0
+                                    strList *bitmaps, Error **errp)
7711c0
+{
7711c0
+    do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
7711c0
 }
7711c0
 
7711c0
 BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
7711c0
diff --git a/qapi/block-core.json b/qapi/block-core.json
7711c0
index 0960449..7e11392 100644
7711c0
--- a/qapi/block-core.json
7711c0
+++ b/qapi/block-core.json
7711c0
@@ -1801,14 +1801,14 @@
7711c0
 #
7711c0
 # @node: name of device/node which the bitmap is tracking
7711c0
 #
7711c0
-# @dst_name: name of the destination dirty bitmap
7711c0
+# @target: name of the destination dirty bitmap
7711c0
 #
7711c0
-# @src_name: name of the source dirty bitmap
7711c0
+# @bitmaps: name(s) of the source dirty bitmap(s)
7711c0
 #
7711c0
 # Since: 3.0
7711c0
 ##
7711c0
 { 'struct': 'BlockDirtyBitmapMerge',
7711c0
-  'data': { 'node': 'str', 'dst_name': 'str', 'src_name': 'str' } }
7711c0
+  'data': { 'node': 'str', 'target': 'str', 'bitmaps': ['str'] } }
7711c0
 
7711c0
 ##
7711c0
 # @block-dirty-bitmap-add:
7711c0
@@ -1923,23 +1923,23 @@
7711c0
 ##
7711c0
 # @x-block-dirty-bitmap-merge:
7711c0
 #
7711c0
-# FIXME: Rename @src_name and @dst_name to src-name and dst-name.
7711c0
-#
7711c0
-# Merge @src_name dirty bitmap to @dst_name dirty bitmap. @src_name dirty
7711c0
-# bitmap is unchanged. On error, @dst_name is unchanged.
7711c0
+# Merge dirty bitmaps listed in @bitmaps to the @target dirty bitmap.
7711c0
+# The @bitmaps dirty bitmaps are unchanged.
7711c0
+# On error, @target is unchanged.
7711c0
 #
7711c0
 # Returns: nothing on success
7711c0
 #          If @node is not a valid block device, DeviceNotFound
7711c0
-#          If @dst_name or @src_name is not found, GenericError
7711c0
-#          If bitmaps has different sizes or granularities, GenericError
7711c0
+#          If any bitmap in @bitmaps or @target is not found, GenericError
7711c0
+#          If any of the bitmaps have different sizes or granularities,
7711c0
+#              GenericError
7711c0
 #
7711c0
 # Since: 3.0
7711c0
 #
7711c0
 # Example:
7711c0
 #
7711c0
 # -> { "execute": "x-block-dirty-bitmap-merge",
7711c0
-#      "arguments": { "node": "drive0", "dst_name": "bitmap0",
7711c0
-#                     "src_name": "bitmap1" } }
7711c0
+#      "arguments": { "node": "drive0", "target": "bitmap0",
7711c0
+#                     "bitmaps": ["bitmap1"] } }
7711c0
 # <- { "return": {} }
7711c0
 #
7711c0
 ##
7711c0
-- 
7711c0
1.8.3.1
7711c0