Blame SOURCES/kvm-nbd-Only-require-disabled-bitmap-for-read-only-expor.patch

7711c0
From 36341fd3c27fd361efe22a7c2758fff1b245867f Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Wed, 27 Mar 2019 17:22:28 +0100
7711c0
Subject: [PATCH 089/163] nbd: Only require disabled bitmap for read-only
7711c0
 exports
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190327172308.31077-16-jsnow@redhat.com>
7711c0
Patchwork-id: 85180
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 15/55] nbd: Only require disabled bitmap for read-only exports
7711c0
Bugzilla: 1691009
7711c0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
7711c0
From: Eric Blake <eblake@redhat.com>
7711c0
7711c0
Our initial implementation of x-nbd-server-add-bitmap put
7711c0
in a restriction because of incremental backups: in that
7711c0
usage, we are exporting one qcow2 file (the temporary overlay
7711c0
target of a blockdev-backup sync:none job) and a dirty bitmap
7711c0
owned by a second qcow2 file (the source of the
7711c0
blockdev-backup, which is the backing file of the temporary).
7711c0
While both qcow2 files are still writable (the target in
7711c0
order to capture copy-on-write of old contents, and the
7711c0
source in order to track live guest writes in the meantime),
7711c0
the NBD client expects to see constant data, including the
7711c0
dirty bitmap.  An enabled bitmap in the source would be
7711c0
modified by guest writes, which is at odds with the NBD
7711c0
export being a read-only constant view, hence the initial
7711c0
code choice of enforcing a disabled bitmap (the intent is
7711c0
that the exposed bitmap was disabled in the same transaction
7711c0
that started the blockdev-backup job, although we don't want
7711c0
to track enough state to actually enforce that).
7711c0
7711c0
However, consider the case of a bitmap contained in a read-only
7711c0
node (including when the bitmap is found in a backing layer of
7711c0
the active image).  Because the node can't be modified, the
7711c0
bitmap won't change due to writes, regardless of whether it is
7711c0
still enabled.  Forbidding the export unless the bitmap is
7711c0
disabled is awkward, paritcularly since we can't change the
7711c0
bitmap to be disabled (because the node is read-only).
7711c0
7711c0
Alternatively, consider the case of live storage migration,
7711c0
where management directs the destination to create a writable
7711c0
NBD server, then performs a drive-mirror from the source to
7711c0
the target, prior to doing the rest of the live migration.
7711c0
Since storage migration can be time-consuming, it may be wise
7711c0
to let the destination include a dirty bitmap to track which
7711c0
portions it has already received, where even if the migration
7711c0
is interrupted and restarted, the source can query the
7711c0
destination block status in order to potentially minimize
7711c0
re-sending data that has not changed in the meantime on a
7711c0
second attempt. Such code has not been written, and might not
7711c0
be trivial (after all, a cluster being marked dirty in the
7711c0
bitmap does not necessarily guarantee it has the desired
7711c0
contents), but it makes sense that letting an active dirty
7711c0
bitmap be exposed and changing alongside writes may prove
7711c0
useful in the future.
7711c0
7711c0
Solve both issues by gating the restriction against a
7711c0
disabled bitmap to only happen when the caller has requested
7711c0
a read-only export, and where the BDS that owns the bitmap
7711c0
(whether or not it is the BDS handed to nbd_export_new() or
7711c0
from its backing chain) is still writable.  We could drop
7711c0
the check altogether (if management apps are prepared to
7711c0
deal with a changing bitmap even on a read-only image), but
7711c0
for now keeping a check for the read-only case still stands
7711c0
a chance of preventing management errors.
7711c0
7711c0
Update iotest 223 to show the looser behavior by leaving
7711c0
a bitmap enabled the whole run; note that we have to tear
7711c0
down and re-export a node when handling an error.
7711c0
7711c0
Signed-off-by: Eric Blake <eblake@redhat.com>
7711c0
Message-Id: <20190111194720.15671-4-eblake@redhat.com>
7711c0
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7711c0
(cherry picked from commit 702aa50d61497d29ef3b5e9c75d1404b3e6fd831)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 nbd/server.c               |  7 +++++--
7711c0
 tests/qemu-iotests/223     | 10 +++++++---
7711c0
 tests/qemu-iotests/223.out |  3 ++-
7711c0
 3 files changed, 14 insertions(+), 6 deletions(-)
7711c0
7711c0
diff --git a/nbd/server.c b/nbd/server.c
7711c0
index abf03e8..c0f2e85 100644
7711c0
--- a/nbd/server.c
7711c0
+++ b/nbd/server.c
7711c0
@@ -2456,8 +2456,11 @@ void nbd_export_bitmap(NBDExport *exp, const char *bitmap,
7711c0
         return;
7711c0
     }
7711c0
 
7711c0
-    if (bdrv_dirty_bitmap_enabled(bm)) {
7711c0
-        error_setg(errp, "Bitmap '%s' is enabled", bitmap);
7711c0
+    if ((exp->nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) &&
7711c0
+        bdrv_dirty_bitmap_enabled(bm)) {
7711c0
+        error_setg(errp,
7711c0
+                   "Enabled bitmap '%s' incompatible with readonly export",
7711c0
+                   bitmap);
7711c0
         return;
7711c0
     }
7711c0
 
7711c0
diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223
7711c0
index a401609..f200e31 100755
7711c0
--- a/tests/qemu-iotests/223
7711c0
+++ b/tests/qemu-iotests/223
7711c0
@@ -61,6 +61,8 @@ echo "=== Create partially sparse image, then add dirty bitmaps ==="
7711c0
 echo
7711c0
 
7711c0
 # Two bitmaps, to contrast granularity issues
7711c0
+# Also note that b will be disabled, while b2 is left enabled, to
7711c0
+# check for read-only interactions
7711c0
 _make_test_img -o cluster_size=4k 4M
7711c0
 $QEMU_IO -c 'w -P 0x11 1M 2M' "$TEST_IMG" | _filter_qemu_io
7711c0
 run_qemu <
7711c0
@@ -134,9 +136,11 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
   "arguments":{"device":"n", "name":"n2"}}' "return"
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
7711c0
-  "arguments":{"name":"n2", "bitmap":"b2"}}' "error" # Attempt enabled bitmap
7711c0
-_send_qemu_cmd $QEMU_HANDLE '{"execute":"block-dirty-bitmap-disable",
7711c0
-  "arguments":{"node":"n", "name":"b2"}}' "return"
7711c0
+  "arguments":{"name":"n2", "bitmap":"b2"}}' "error" # Enabled vs. read-only
7711c0
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
7711c0
+  "arguments":{"name":"n2"}}' "return"
7711c0
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
+  "arguments":{"device":"n", "name":"n2", "writable":true}}' "return"
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
7711c0
   "arguments":{"name":"n2", "bitmap":"b2"}}' "return"
7711c0
 
7711c0
diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out
7711c0
index 7d28c1a..3028857 100644
7711c0
--- a/tests/qemu-iotests/223.out
7711c0
+++ b/tests/qemu-iotests/223.out
7711c0
@@ -35,7 +35,8 @@ wrote 2097152/2097152 bytes at offset 2097152
7711c0
 {"error": {"class": "GenericError", "desc": "NBD server already has export named 'n'"}}
7711c0
 {"return": {}}
7711c0
 {"return": {}}
7711c0
-{"error": {"class": "GenericError", "desc": "Bitmap 'b2' is enabled"}}
7711c0
+{"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}}
7711c0
+{"return": {}}
7711c0
 {"return": {}}
7711c0
 {"return": {}}
7711c0
 
7711c0
-- 
7711c0
1.8.3.1
7711c0