26ba25
From 09e6d08bc3cb4c80b508d2e72f861fdb1b5612ea Mon Sep 17 00:00:00 2001
26ba25
From: John Snow <jsnow@redhat.com>
26ba25
Date: Wed, 18 Jul 2018 22:55:10 +0200
26ba25
Subject: [PATCH 252/268] nbd/client: Add x-dirty-bitmap to query bitmap from
26ba25
 server
26ba25
26ba25
RH-Author: John Snow <jsnow@redhat.com>
26ba25
Message-id: <20180718225511.14878-35-jsnow@redhat.com>
26ba25
Patchwork-id: 81414
26ba25
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 34/35] nbd/client: Add x-dirty-bitmap to query bitmap from server
26ba25
Bugzilla: 1207657
26ba25
RH-Acked-by: Eric Blake <eblake@redhat.com>
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
RH-Acked-by: Fam Zheng <famz@redhat.com>
26ba25
26ba25
From: Eric Blake <eblake@redhat.com>
26ba25
26ba25
In order to test that the NBD server is properly advertising
26ba25
dirty bitmaps, we need a bare minimum client that can request
26ba25
and read the context.  Since feature freeze for 3.0 is imminent,
26ba25
this is the smallest workable patch, which replaces the qemu
26ba25
block status report with the results of the NBD server's dirty
26ba25
bitmap (making it very easy to use 'qemu-img map --output=json'
26ba25
to learn where the dirty portions are).  Note that the NBD
26ba25
protocol defines a dirty section with the same bit but opposite
26ba25
sense that normal "base:allocation" uses to report an allocated
26ba25
section; so in qemu-img map output, "data":true corresponds to
26ba25
clean, "data":false corresponds to dirty.
26ba25
26ba25
A more complete solution that allows dirty bitmaps to be queried
26ba25
at the same time as normal block status will be required before
26ba25
this addition can lose the x- prefix.  Until then, the fact that
26ba25
this replaces normal status with dirty status means actions
26ba25
like 'qemu-img convert' will likely misbehave due to treating
26ba25
dirty regions of the file as if they are unallocated.
26ba25
26ba25
The next patch adds an iotest to exercise this new code.
26ba25
26ba25
Signed-off-by: Eric Blake <eblake@redhat.com>
26ba25
Message-Id: <20180702191458.28741-2-eblake@redhat.com>
26ba25
(cherry picked from commit 216ee3657e14013505abe7853cecb632199fb13e)
26ba25
Signed-off-by: John Snow <jsnow@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/nbd-client.c   |  3 +++
26ba25
 block/nbd-client.h   |  1 +
26ba25
 block/nbd.c          | 10 ++++++++--
26ba25
 include/block/nbd.h  |  1 +
26ba25
 nbd/client.c         |  4 ++--
26ba25
 qapi/block-core.json |  7 ++++++-
26ba25
 6 files changed, 21 insertions(+), 5 deletions(-)
26ba25
26ba25
diff --git a/block/nbd-client.c b/block/nbd-client.c
26ba25
index e7caf49..98637c0 100644
26ba25
--- a/block/nbd-client.c
26ba25
+++ b/block/nbd-client.c
26ba25
@@ -966,6 +966,7 @@ int nbd_client_init(BlockDriverState *bs,
26ba25
                     const char *export,
26ba25
                     QCryptoTLSCreds *tlscreds,
26ba25
                     const char *hostname,
26ba25
+                    const char *x_dirty_bitmap,
26ba25
                     Error **errp)
26ba25
 {
26ba25
     NBDClientSession *client = nbd_get_client_session(bs);
26ba25
@@ -978,9 +979,11 @@ int nbd_client_init(BlockDriverState *bs,
26ba25
     client->info.request_sizes = true;
26ba25
     client->info.structured_reply = true;
26ba25
     client->info.base_allocation = true;
26ba25
+    client->info.x_dirty_bitmap = g_strdup(x_dirty_bitmap);
26ba25
     ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), export,
26ba25
                                 tlscreds, hostname,
26ba25
                                 &client->ioc, &client->info, errp);
26ba25
+    g_free(client->info.x_dirty_bitmap);
26ba25
     if (ret < 0) {
26ba25
         logout("Failed to negotiate with the NBD server\n");
26ba25
         return ret;
26ba25
diff --git a/block/nbd-client.h b/block/nbd-client.h
26ba25
index 0ece76e..cfc9055 100644
26ba25
--- a/block/nbd-client.h
26ba25
+++ b/block/nbd-client.h
26ba25
@@ -45,6 +45,7 @@ int nbd_client_init(BlockDriverState *bs,
26ba25
                     const char *export_name,
26ba25
                     QCryptoTLSCreds *tlscreds,
26ba25
                     const char *hostname,
26ba25
+                    const char *x_dirty_bitmap,
26ba25
                     Error **errp);
26ba25
 void nbd_client_close(BlockDriverState *bs);
26ba25
 
26ba25
diff --git a/block/nbd.c b/block/nbd.c
26ba25
index 10912c3..f29c10f 100644
26ba25
--- a/block/nbd.c
26ba25
+++ b/block/nbd.c
26ba25
@@ -378,6 +378,12 @@ static QemuOptsList nbd_runtime_opts = {
26ba25
             .type = QEMU_OPT_STRING,
26ba25
             .help = "ID of the TLS credentials to use",
26ba25
         },
26ba25
+        {
26ba25
+            .name = "x-dirty-bitmap",
26ba25
+            .type = QEMU_OPT_STRING,
26ba25
+            .help = "experimental: expose named dirty bitmap in place of "
26ba25
+                    "block status",
26ba25
+        },
26ba25
         { /* end of list */ }
26ba25
     },
26ba25
 };
26ba25
@@ -438,8 +444,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
26ba25
     }
26ba25
 
26ba25
     /* NBD handshake */
26ba25
-    ret = nbd_client_init(bs, sioc, s->export,
26ba25
-                          tlscreds, hostname, errp);
26ba25
+    ret = nbd_client_init(bs, sioc, s->export, tlscreds, hostname,
26ba25
+                          qemu_opt_get(opts, "x-dirty-bitmap"), errp);
26ba25
  error:
26ba25
     if (sioc) {
26ba25
         object_unref(OBJECT(sioc));
26ba25
diff --git a/include/block/nbd.h b/include/block/nbd.h
26ba25
index daaeae6..4638c83 100644
26ba25
--- a/include/block/nbd.h
26ba25
+++ b/include/block/nbd.h
26ba25
@@ -259,6 +259,7 @@ static inline bool nbd_reply_type_is_error(int type)
26ba25
 struct NBDExportInfo {
26ba25
     /* Set by client before nbd_receive_negotiate() */
26ba25
     bool request_sizes;
26ba25
+    char *x_dirty_bitmap;
26ba25
 
26ba25
     /* In-out fields, set by client before nbd_receive_negotiate() and
26ba25
      * updated by server results during nbd_receive_negotiate() */
26ba25
diff --git a/nbd/client.c b/nbd/client.c
26ba25
index b9e175d..25603f2 100644
26ba25
--- a/nbd/client.c
26ba25
+++ b/nbd/client.c
26ba25
@@ -1,5 +1,5 @@
26ba25
 /*
26ba25
- *  Copyright (C) 2016-2017 Red Hat, Inc.
26ba25
+ *  Copyright (C) 2016-2018 Red Hat, Inc.
26ba25
  *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
26ba25
  *
26ba25
  *  Network Block Device Client Side
26ba25
@@ -825,7 +825,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
26ba25
 
26ba25
             if (info->structured_reply && base_allocation) {
26ba25
                 result = nbd_negotiate_simple_meta_context(
26ba25
-                        ioc, name, "base:allocation",
26ba25
+                        ioc, name, info->x_dirty_bitmap ?: "base:allocation",
26ba25
                         &info->meta_base_allocation_id, errp);
26ba25
                 if (result < 0) {
26ba25
                     goto fail;
26ba25
diff --git a/qapi/block-core.json b/qapi/block-core.json
26ba25
index b2de7af..a6399af 100644
26ba25
--- a/qapi/block-core.json
26ba25
+++ b/qapi/block-core.json
26ba25
@@ -3457,12 +3457,17 @@
26ba25
 #
26ba25
 # @tls-creds:   TLS credentials ID
26ba25
 #
26ba25
+# @x-dirty-bitmap: A "qemu:dirty-bitmap:NAME" string to query in place of
26ba25
+#                  traditional "base:allocation" block status (see
26ba25
+#                  NBD_OPT_LIST_META_CONTEXT in the NBD protocol) (since 3.0)
26ba25
+#
26ba25
 # Since: 2.9
26ba25
 ##
26ba25
 { 'struct': 'BlockdevOptionsNbd',
26ba25
   'data': { 'server': 'SocketAddress',
26ba25
             '*export': 'str',
26ba25
-            '*tls-creds': 'str' } }
26ba25
+            '*tls-creds': 'str',
26ba25
+            '*x-dirty-bitmap': 'str' } }
26ba25
 
26ba25
 ##
26ba25
 # @BlockdevOptionsRaw:
26ba25
-- 
26ba25
1.8.3.1
26ba25