Blame SOURCES/kvm-nbd-Allow-bitmap-export-during-QMP-nbd-server-add.patch

7711c0
From d5c834ab75d9e3e67e6f8489fef32dc4d22443a1 Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Wed, 27 Mar 2019 17:22:30 +0100
7711c0
Subject: [PATCH 091/163] nbd: Allow bitmap export during QMP nbd-server-add
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190327172308.31077-18-jsnow@redhat.com>
7711c0
Patchwork-id: 85188
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 17/55] nbd: Allow bitmap export during QMP nbd-server-add
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
With the experimental x-nbd-server-add-bitmap command, there was
7711c0
a window of time where an NBD client could see the export but not
7711c0
the associated dirty bitmap, which can cause a client that planned
7711c0
on using the dirty bitmap to be forced to treat the entire image
7711c0
as dirty as a safety fallback.  Furthermore, if the QMP client
7711c0
successfully exports a disk but then fails to add the bitmap, it
7711c0
has to take on the burden of removing the export.  Since we don't
7711c0
allow changing the exposed dirty bitmap (whether to a different
7711c0
bitmap, or removing advertisement of the bitmap), it is nicer to
7711c0
make the bitmap tied to the export at the time the export is
7711c0
created, with automatic failure to export if the bitmap is not
7711c0
available.
7711c0
7711c0
The experimental command included an optional 'bitmap-export-name'
7711c0
field for remapping the name exposed over NBD to be different from
7711c0
the bitmap name stored on disk.  However, my libvirt demo code
7711c0
for implementing differential backups on top of persistent bitmaps
7711c0
did not need to take advantage of that feature (it is instead
7711c0
possible to create a new temporary bitmap with the desired name,
7711c0
use block-dirty-bitmap-merge to merge one or more persistent
7711c0
bitmaps into the temporary, then associate the temporary with the
7711c0
NBD export, if control is needed over the exported bitmap name).
7711c0
Hence, I'm not copying that part of the experiment over to the
7711c0
stable addition. For more details on the libvirt demo, see
7711c0
https://www.redhat.com/archives/libvir-list/2018-October/msg01254.html,
7711c0
https://kvmforum2018.sched.com/event/FzuB/facilitating-incremental-backup-eric-blake-red-hat
7711c0
7711c0
This patch focuses on the user interface, and reduces (but does
7711c0
not completely eliminate) the window where an NBD client can see
7711c0
the export but not the dirty bitmap, with less work to clean up
7711c0
after errors.  Later patches will add further cleanups now that
7711c0
this interface is declared stable via a single QMP command,
7711c0
including removing the race window.
7711c0
7711c0
Update test 223 to use the new interface.
7711c0
7711c0
Signed-off-by: Eric Blake <eblake@redhat.com>
7711c0
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7711c0
Message-Id: <20190111194720.15671-6-eblake@redhat.com>
7711c0
(cherry picked from commit 5fcbeb06812685a2c6d7e0e6f28f018987d08b79)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 blockdev-nbd.c             | 12 +++++++++++-
7711c0
 hmp.c                      |  5 +++--
7711c0
 qapi/block.json            |  7 ++++++-
7711c0
 tests/qemu-iotests/223     | 19 ++++++++-----------
7711c0
 tests/qemu-iotests/223.out |  5 +----
7711c0
 5 files changed, 29 insertions(+), 19 deletions(-)
7711c0
7711c0
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
7711c0
index 582ffde..ec8cf0a 100644
7711c0
--- a/blockdev-nbd.c
7711c0
+++ b/blockdev-nbd.c
7711c0
@@ -140,7 +140,8 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
7711c0
 }
7711c0
 
7711c0
 void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
7711c0
-                        bool has_writable, bool writable, Error **errp)
7711c0
+                        bool has_writable, bool writable,
7711c0
+                        bool has_bitmap, const char *bitmap, Error **errp)
7711c0
 {
7711c0
     BlockDriverState *bs = NULL;
7711c0
     BlockBackend *on_eject_blk;
7711c0
@@ -185,6 +186,15 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
7711c0
      * our only way of accessing it is through nbd_export_find(), so we can drop
7711c0
      * the strong reference that is @exp. */
7711c0
     nbd_export_put(exp);
7711c0
+
7711c0
+    if (has_bitmap) {
7711c0
+        Error *err = NULL;
7711c0
+        nbd_export_bitmap(exp, bitmap, bitmap, &err;;
7711c0
+        if (err) {
7711c0
+            error_propagate(errp, err);
7711c0
+            nbd_export_remove(exp, NBD_SERVER_REMOVE_MODE_HARD, NULL);
7711c0
+        }
7711c0
+    }
7711c0
 }
7711c0
 
7711c0
 void qmp_nbd_server_remove(const char *name,
7711c0
diff --git a/hmp.c b/hmp.c
7711c0
index cc088da..59e52b9 100644
7711c0
--- a/hmp.c
7711c0
+++ b/hmp.c
7711c0
@@ -2212,7 +2212,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
7711c0
         }
7711c0
 
7711c0
         qmp_nbd_server_add(info->value->device, false, NULL,
7711c0
-                           true, writable, &local_err);
7711c0
+                           true, writable, false, NULL, &local_err);
7711c0
 
7711c0
         if (local_err != NULL) {
7711c0
             qmp_nbd_server_stop(NULL);
7711c0
@@ -2233,7 +2233,8 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
7711c0
     bool writable = qdict_get_try_bool(qdict, "writable", false);
7711c0
     Error *local_err = NULL;
7711c0
 
7711c0
-    qmp_nbd_server_add(device, !!name, name, true, writable, &local_err);
7711c0
+    qmp_nbd_server_add(device, !!name, name, true, writable,
7711c0
+                       false, NULL, &local_err);
7711c0
     hmp_handle_error(mon, &local_err);
7711c0
 }
7711c0
 
7711c0
diff --git a/qapi/block.json b/qapi/block.json
7711c0
index ba85ceb..b04fcdc 100644
7711c0
--- a/qapi/block.json
7711c0
+++ b/qapi/block.json
7711c0
@@ -313,6 +313,10 @@
7711c0
 #
7711c0
 # @writable: Whether clients should be able to write to the device via the
7711c0
 #     NBD connection (default false).
7711c0
+
7711c0
+# @bitmap: Also export the dirty bitmap reachable from @device, so the
7711c0
+#          NBD client can use NBD_OPT_SET_META_CONTEXT with
7711c0
+#          "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
7711c0
 #
7711c0
 # Returns: error if the server is not running, or export with the same name
7711c0
 #          already exists.
7711c0
@@ -320,7 +324,8 @@
7711c0
 # Since: 1.3.0
7711c0
 ##
7711c0
 { 'command': 'nbd-server-add',
7711c0
-  'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} }
7711c0
+  'data': {'device': 'str', '*name': 'str', '*writable': 'bool',
7711c0
+           '*bitmap': 'str' } }
7711c0
 
7711c0
 ##
7711c0
 # @NbdServerRemoveMode:
7711c0
diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223
7711c0
index f200e31..0bcc98a 100755
7711c0
--- a/tests/qemu-iotests/223
7711c0
+++ b/tests/qemu-iotests/223
7711c0
@@ -126,23 +126,20 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
7711c0
   "arguments":{"addr":{"type":"unix",
7711c0
     "data":{"path":"'"$TEST_DIR/nbd"1'"}}}}' "error" # Attempt second server
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
-  "arguments":{"device":"n"}}' "return"
7711c0
+  "arguments":{"device":"n", "bitmap":"b"}}' "return"
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
   "arguments":{"device":"nosuch"}}' "error" # Attempt to export missing node
7711c0
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
   "arguments":{"device":"n"}}' "error" # Attempt to export same name twice
7711c0
-_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
7711c0
-  "arguments":{"name":"n", "bitmap":"b"}}' "return"
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" # Enabled vs. read-only
7711c0
-_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
7711c0
-  "arguments":{"name":"n2"}}' "return"
7711c0
+  "arguments":{"device":"n", "name":"n2",
7711c0
+  "bitmap":"b2"}}' "error" # enabled vs. read-only
7711c0
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
7711c0
+  "arguments":{"device":"n", "name":"n2",
7711c0
+  "bitmap":"b3"}}' "error" # Missing bitmap
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
+  "arguments":{"device":"n", "name":"n2", "writable":true,
7711c0
+  "bitmap":"b2"}}' "return"
7711c0
 
7711c0
 echo
7711c0
 echo "=== Contrast normal status to large granularity dirty-bitmap ==="
7711c0
diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out
7711c0
index 3028857..a0c2dec 100644
7711c0
--- a/tests/qemu-iotests/223.out
7711c0
+++ b/tests/qemu-iotests/223.out
7711c0
@@ -33,11 +33,8 @@ wrote 2097152/2097152 bytes at offset 2097152
7711c0
 {"return": {}}
7711c0
 {"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}}
7711c0
 {"error": {"class": "GenericError", "desc": "NBD server already has export named 'n'"}}
7711c0
-{"return": {}}
7711c0
-{"return": {}}
7711c0
 {"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}}
7711c0
-{"return": {}}
7711c0
-{"return": {}}
7711c0
+{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}}
7711c0
 {"return": {}}
7711c0
 
7711c0
 === Contrast normal status to large granularity dirty-bitmap ===
7711c0
-- 
7711c0
1.8.3.1
7711c0