Blame SOURCES/kvm-nbd-Merge-nbd_export_set_name-into-nbd_export_new.patch

383d26
From 629f726f14a40cfe4edf74ec0d213eed935e5a79 Mon Sep 17 00:00:00 2001
383d26
From: John Snow <jsnow@redhat.com>
383d26
Date: Wed, 27 Mar 2019 17:22:29 +0100
383d26
Subject: [PATCH 090/163] nbd: Merge nbd_export_set_name into nbd_export_new
383d26
383d26
RH-Author: John Snow <jsnow@redhat.com>
383d26
Message-id: <20190327172308.31077-17-jsnow@redhat.com>
383d26
Patchwork-id: 85171
383d26
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 16/55] nbd: Merge nbd_export_set_name into nbd_export_new
383d26
Bugzilla: 1691009
383d26
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
RH-Acked-by: Max Reitz <mreitz@redhat.com>
383d26
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
383d26
From: Eric Blake <eblake@redhat.com>
383d26
383d26
The existing NBD code had a weird split where nbd_export_new()
383d26
created an export but did not add it to the list of exported
383d26
names until a later nbd_export_set_name() came along and grabbed
383d26
a second reference on the object; later, the first call to
383d26
nbd_export_close() drops the second reference while removing
383d26
the export from the list.  This is in part because the QAPI
383d26
NbdServerRemoveNode enum documents the possibility of adding a
383d26
mode where we could do a soft disconnect: preventing new clients,
383d26
but waiting for existing clients to gracefully quit, based on
383d26
the mode used when calling nbd_export_close().
383d26
383d26
But in spite of all that, note that we never change the name of
383d26
an NBD export while it is exposed, which means it is easier to
383d26
just inline the process of setting the name as part of creating
383d26
the export.
383d26
383d26
Inline the contents of nbd_export_set_name() and
383d26
nbd_export_set_description() into the two points in an export
383d26
lifecycle where they matter, then adjust both callers to pass
383d26
the name up front.  Note that for creation, all callers pass a
383d26
non-NULL name, (passing NULL at creation was for old style
383d26
servers, but we removed support for that in commit 7f7dfe2a),
383d26
so we can add an assert and do things unconditionally; but for
383d26
cleanup, because of the dual nature of nbd_export_close(), we
383d26
still have to be careful to avoid use-after-free.  Along the
383d26
way, add a comment reminding ourselves of the potential of
383d26
adding a middle mode disconnect.
383d26
383d26
Signed-off-by: Eric Blake <eblake@redhat.com>
383d26
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
383d26
Message-Id: <20190111194720.15671-5-eblake@redhat.com>
383d26
(cherry picked from commit 3fa4c76590569f9dc128beb3eee65aaefcb6321e)
383d26
Signed-off-by: John Snow <jsnow@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 blockdev-nbd.c      |  5 ++---
383d26
 include/block/nbd.h |  3 +--
383d26
 nbd/server.c        | 52 +++++++++++++++++++++++-----------------------------
383d26
 qemu-nbd.c          |  8 +++-----
383d26
 4 files changed, 29 insertions(+), 39 deletions(-)
383d26
383d26
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
383d26
index ca58491..582ffde 100644
383d26
--- a/blockdev-nbd.c
383d26
+++ b/blockdev-nbd.c
383d26
@@ -174,14 +174,13 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
383d26
         writable = false;
383d26
     }
383d26
 
383d26
-    exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY,
383d26
+    exp = nbd_export_new(bs, 0, -1, name, NULL,
383d26
+                         writable ? 0 : NBD_FLAG_READ_ONLY,
383d26
                          NULL, false, on_eject_blk, errp);
383d26
     if (!exp) {
383d26
         return;
383d26
     }
383d26
 
383d26
-    nbd_export_set_name(exp, name);
383d26
-
383d26
     /* The list of named exports has a strong reference to this export now and
383d26
      * our only way of accessing it is through nbd_export_find(), so we can drop
383d26
      * the strong reference that is @exp. */
383d26
diff --git a/include/block/nbd.h b/include/block/nbd.h
383d26
index 65402d3..2f9a2ae 100644
383d26
--- a/include/block/nbd.h
383d26
+++ b/include/block/nbd.h
383d26
@@ -295,6 +295,7 @@ typedef struct NBDExport NBDExport;
383d26
 typedef struct NBDClient NBDClient;
383d26
 
383d26
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
383d26
+                          const char *name, const char *description,
383d26
                           uint16_t nbdflags, void (*close)(NBDExport *),
383d26
                           bool writethrough, BlockBackend *on_eject_blk,
383d26
                           Error **errp);
383d26
@@ -306,8 +307,6 @@ void nbd_export_put(NBDExport *exp);
383d26
 BlockBackend *nbd_export_get_blockdev(NBDExport *exp);
383d26
 
383d26
 NBDExport *nbd_export_find(const char *name);
383d26
-void nbd_export_set_name(NBDExport *exp, const char *name);
383d26
-void nbd_export_set_description(NBDExport *exp, const char *description);
383d26
 void nbd_export_close_all(void);
383d26
 
383d26
 void nbd_client_new(QIOChannelSocket *sioc,
383d26
diff --git a/nbd/server.c b/nbd/server.c
383d26
index c0f2e85..6c02b57 100644
383d26
--- a/nbd/server.c
383d26
+++ b/nbd/server.c
383d26
@@ -1456,6 +1456,7 @@ static void nbd_eject_notifier(Notifier *n, void *data)
383d26
 }
383d26
 
383d26
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
383d26
+                          const char *name, const char *description,
383d26
                           uint16_t nbdflags, void (*close)(NBDExport *),
383d26
                           bool writethrough, BlockBackend *on_eject_blk,
383d26
                           Error **errp)
383d26
@@ -1471,6 +1472,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
383d26
      * that BDRV_O_INACTIVE is cleared and the image is ready for write
383d26
      * access since the export could be available before migration handover.
383d26
      */
383d26
+    assert(name);
383d26
     ctx = bdrv_get_aio_context(bs);
383d26
     aio_context_acquire(ctx);
383d26
     bdrv_invalidate_cache(bs, NULL);
383d26
@@ -1494,6 +1496,8 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
383d26
     QTAILQ_INIT(&exp->clients);
383d26
     exp->blk = blk;
383d26
     exp->dev_offset = dev_offset;
383d26
+    exp->name = g_strdup(name);
383d26
+    exp->description = g_strdup(description);
383d26
     exp->nbdflags = nbdflags;
383d26
     exp->size = size < 0 ? blk_getlength(blk) : size;
383d26
     if (exp->size < 0) {
383d26
@@ -1513,10 +1517,14 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
383d26
         exp->eject_notifier.notify = nbd_eject_notifier;
383d26
         blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier);
383d26
     }
383d26
+    QTAILQ_INSERT_TAIL(&exports, exp, next);
383d26
+    nbd_export_get(exp);
383d26
     return exp;
383d26
 
383d26
 fail:
383d26
     blk_unref(blk);
383d26
+    g_free(exp->name);
383d26
+    g_free(exp->description);
383d26
     g_free(exp);
383d26
     return NULL;
383d26
 }
383d26
@@ -1533,43 +1541,29 @@ NBDExport *nbd_export_find(const char *name)
383d26
     return NULL;
383d26
 }
383d26
 
383d26
-void nbd_export_set_name(NBDExport *exp, const char *name)
383d26
-{
383d26
-    if (exp->name == name) {
383d26
-        return;
383d26
-    }
383d26
-
383d26
-    nbd_export_get(exp);
383d26
-    if (exp->name != NULL) {
383d26
-        g_free(exp->name);
383d26
-        exp->name = NULL;
383d26
-        QTAILQ_REMOVE(&exports, exp, next);
383d26
-        nbd_export_put(exp);
383d26
-    }
383d26
-    if (name != NULL) {
383d26
-        nbd_export_get(exp);
383d26
-        exp->name = g_strdup(name);
383d26
-        QTAILQ_INSERT_TAIL(&exports, exp, next);
383d26
-    }
383d26
-    nbd_export_put(exp);
383d26
-}
383d26
-
383d26
-void nbd_export_set_description(NBDExport *exp, const char *description)
383d26
-{
383d26
-    g_free(exp->description);
383d26
-    exp->description = g_strdup(description);
383d26
-}
383d26
-
383d26
 void nbd_export_close(NBDExport *exp)
383d26
 {
383d26
     NBDClient *client, *next;
383d26
 
383d26
     nbd_export_get(exp);
383d26
+    /*
383d26
+     * TODO: Should we expand QMP NbdServerRemoveNode enum to allow a
383d26
+     * close mode that stops advertising the export to new clients but
383d26
+     * still permits existing clients to run to completion? Because of
383d26
+     * that possibility, nbd_export_close() can be called more than
383d26
+     * once on an export.
383d26
+     */
383d26
     QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
383d26
         client_close(client, true);
383d26
     }
383d26
-    nbd_export_set_name(exp, NULL);
383d26
-    nbd_export_set_description(exp, NULL);
383d26
+    if (exp->name) {
383d26
+        nbd_export_put(exp);
383d26
+        g_free(exp->name);
383d26
+        exp->name = NULL;
383d26
+        QTAILQ_REMOVE(&exports, exp, next);
383d26
+    }
383d26
+    g_free(exp->description);
383d26
+    exp->description = NULL;
383d26
     nbd_export_put(exp);
383d26
 }
383d26
 
383d26
diff --git a/qemu-nbd.c b/qemu-nbd.c
383d26
index c37defb..c85aee4 100644
383d26
--- a/qemu-nbd.c
383d26
+++ b/qemu-nbd.c
383d26
@@ -1017,11 +1017,9 @@ int main(int argc, char **argv)
383d26
         }
383d26
     }
383d26
 
383d26
-    export = nbd_export_new(bs, dev_offset, fd_size, nbdflags,
383d26
-                            nbd_export_closed, writethrough,
383d26
-                            NULL, &error_fatal);
383d26
-    nbd_export_set_name(export, export_name);
383d26
-    nbd_export_set_description(export, export_description);
383d26
+    export = nbd_export_new(bs, dev_offset, fd_size, export_name,
383d26
+                            export_description, nbdflags, nbd_export_closed,
383d26
+                            writethrough, NULL, &error_fatal);
383d26
 
383d26
     if (device) {
383d26
 #if HAVE_NBD_DEVICE
383d26
-- 
383d26
1.8.3.1
383d26