qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com
Subject: [RFC PATCH 20/22] block/export: Add block-export-del
Date: Thu, 13 Aug 2020 18:29:33 +0200	[thread overview]
Message-ID: <20200813162935.210070-21-kwolf@redhat.com> (raw)
In-Reply-To: <20200813162935.210070-1-kwolf@redhat.com>

Implement a new QMP command block-export-del and make nbd-server-remove
a wrapper around it.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qapi/block-export.json         | 30 +++++++++++++++----
 include/block/nbd.h            |  1 -
 block/export/export.c          | 54 ++++++++++++++++++++++++++++++++++
 block/monitor/block-hmp-cmds.c |  2 +-
 blockdev-nbd.c                 | 28 ------------------
 nbd/server.c                   | 14 ---------
 6 files changed, 79 insertions(+), 50 deletions(-)

diff --git a/qapi/block-export.json b/qapi/block-export.json
index 0d0db9ca1b..a067de2ba3 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -111,9 +111,9 @@
   'data': 'NbdServerAddOptions', 'boxed': true }
 
 ##
-# @NbdServerRemoveMode:
+# @BlockExportRemoveMode:
 #
-# Mode for removing an NBD export.
+# Mode for removing a block export.
 #
 # @safe: Remove export if there are no existing connections, fail otherwise.
 #
@@ -129,16 +129,16 @@
 #
 # Since: 2.12
 ##
-{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
+{'enum': 'BlockExportRemoveMode', 'data': ['safe', 'hard']}
 
 ##
 # @nbd-server-remove:
 #
 # Remove NBD export by name.
 #
-# @name: Export name.
+# @name: Block export id.
 #
-# @mode: Mode of command operation. See @NbdServerRemoveMode description.
+# @mode: Mode of command operation. See @BlockExportRemoveMode description.
 #        Default is 'safe'.
 #
 # Returns: error if
@@ -149,7 +149,7 @@
 # Since: 2.12
 ##
 { 'command': 'nbd-server-remove',
-  'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
+  'data': {'name': 'str', '*mode': 'BlockExportRemoveMode'} }
 
 ##
 # @nbd-server-stop:
@@ -208,3 +208,21 @@
 ##
 { 'command': 'block-export-add',
   'data': 'BlockExportOptions', 'boxed': true }
+
+##
+# @block-export-del:
+#
+# Remove a block export.
+#
+# @id: Block export id.
+#
+# @mode: Mode of command operation. See @BlockExportRemoveMode description.
+#        Default is 'safe'.
+#
+# Returns: Error if the export is not found or @mode is 'safe' and the export
+#          is still in use (e.g. by existing client connections)
+#
+# Since: 5.2
+##
+{ 'command': 'block-export-del',
+  'data': { 'id': 'str', '*mode': 'BlockExportRemoveMode' } }
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 91a9d4f96d..7982a63f96 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -335,7 +335,6 @@ int nbd_export_new(BlockExport *blk_exp, BlockDriverState *bs,
                    const char *bitmap, bool readonly, bool shared,
                    bool writethrough, Error **errp);
 void nbd_export_set_on_eject_blk(BlockExport *exp, BlockBackend *blk);
-void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp);
 
 AioContext *nbd_export_aio_context(NBDExport *exp);
 NBDExport *nbd_export_find(const char *name);
diff --git a/block/export/export.c b/block/export/export.c
index f94a81258a..1255f3fc80 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -115,6 +115,15 @@ void blk_exp_request_shutdown(BlockExport *exp)
 {
     AioContext *aio_context = exp->ctx;
 
+    /*
+     * If the user doesn't own the export any more, it is already shutting
+     * down. We must not call .request_shutdown and decrease the refcount a
+     * second time.
+     */
+    if (!exp->user_owned) {
+        return;
+    }
+
     aio_context_acquire(aio_context);
     exp->drv->request_shutdown(exp);
     aio_context_release(aio_context);
@@ -215,3 +224,48 @@ void qmp_nbd_server_add(NbdServerAddOptions *arg, Error **errp)
 fail:
     qapi_free_BlockExportOptions(export_opts);
 }
+
+void qmp_block_export_del(const char *id,
+                          bool has_mode, BlockExportRemoveMode mode,
+                          Error **errp)
+{
+    ERRP_GUARD();
+    BlockExport *exp;
+
+    exp = blk_exp_find(id);
+    if (exp == NULL) {
+        error_setg(errp, "Export '%s' is not found", id);
+        return;
+    }
+    if (!exp->user_owned) {
+        error_setg(errp, "Export '%s' is already shutting down", id);
+        return;
+    }
+
+    if (!has_mode) {
+        mode = BLOCK_EXPORT_REMOVE_MODE_SAFE;
+    }
+    if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && exp->refcount > 1) {
+        error_setg(errp, "export '%s' still in use", exp->id);
+        error_append_hint(errp, "Use mode='hard' to force client "
+                          "disconnect\n");
+        return;
+    }
+
+    blk_exp_request_shutdown(exp);
+}
+
+void qmp_nbd_server_remove(const char *name,
+                           bool has_mode, BlockExportRemoveMode mode,
+                           Error **errp)
+{
+    BlockExport *exp;
+
+    exp = blk_exp_find(name);
+    if (exp && exp->drv->type != BLOCK_EXPORT_TYPE_NBD) {
+        error_setg(errp, "Block export '%s' is not an NBD export", name);
+        return;
+    }
+
+    qmp_block_export_del(name, has_mode, mode, errp);
+}
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 6c823234a9..10165252cf 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -477,7 +477,7 @@ void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
     Error *err = NULL;
 
     /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
-    qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err);
+    qmp_nbd_server_remove(name, force, BLOCK_EXPORT_REMOVE_MODE_HARD, &err);
     hmp_handle_error(mon, err);
 }
 
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 40013b7d64..5ec21045a8 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -237,34 +237,6 @@ int nbd_export_create(BlockExport *exp, BlockExportOptions *exp_args,
     return ret;
 }
 
-void qmp_nbd_server_remove(const char *name,
-                           bool has_mode, NbdServerRemoveMode mode,
-                           Error **errp)
-{
-    NBDExport *exp;
-    AioContext *aio_context;
-
-    if (!nbd_server) {
-        error_setg(errp, "NBD server not running");
-        return;
-    }
-
-    exp = nbd_export_find(name);
-    if (exp == NULL) {
-        error_setg(errp, "Export '%s' is not found", name);
-        return;
-    }
-
-    if (!has_mode) {
-        mode = NBD_SERVER_REMOVE_MODE_SAFE;
-    }
-
-    aio_context = nbd_export_aio_context(exp);
-    aio_context_acquire(aio_context);
-    nbd_export_remove(exp, mode, errp);
-    aio_context_release(aio_context);
-}
-
 void qmp_nbd_server_stop(Error **errp)
 {
     if (!nbd_server) {
diff --git a/nbd/server.c b/nbd/server.c
index e3ac7f548b..899d00782f 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1669,20 +1669,6 @@ static void nbd_export_request_shutdown(BlockExport *blk_exp)
     blk_exp_unref(&exp->common);
 }
 
-void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp)
-{
-    ERRP_GUARD();
-    if (mode == NBD_SERVER_REMOVE_MODE_HARD || QTAILQ_EMPTY(&exp->clients)) {
-        nbd_export_request_shutdown(&exp->common);
-        return;
-    }
-
-    assert(mode == NBD_SERVER_REMOVE_MODE_SAFE);
-
-    error_setg(errp, "export '%s' still in use", exp->name);
-    error_append_hint(errp, "Use mode='hard' to force client disconnect\n");
-}
-
 static void nbd_export_delete(BlockExport *blk_exp)
 {
     NBDExport *exp = container_of(blk_exp, NBDExport, common);
-- 
2.25.4



  parent reply	other threads:[~2020-08-13 16:39 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-13 16:29 [RFC PATCH 00/22] block/export: Add infrastructure and QAPI for block exports Kevin Wolf
2020-08-13 16:29 ` [RFC PATCH 01/22] nbd: Remove unused nbd_export_get_blockdev() Kevin Wolf
2020-08-17  8:14   ` Max Reitz
2020-08-19 18:13   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 02/22] qapi: Create block-export module Kevin Wolf
2020-08-17  8:50   ` Max Reitz
2020-08-19 18:17   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 03/22] qapi: Rename BlockExport to BlockExportOptions Kevin Wolf
2020-08-17  9:13   ` Max Reitz
2020-08-19 18:19   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 04/22] block/export: Add BlockExport infrastructure and block-export-add Kevin Wolf
2020-08-17 10:03   ` Max Reitz
2020-08-17 12:45     ` Kevin Wolf
2020-08-17 13:19       ` Max Reitz
2020-08-17 13:29         ` Kevin Wolf
2020-08-17 13:53           ` Max Reitz
2020-08-19 18:31   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 05/22] qemu-storage-daemon: Use qmp_block_export_add() Kevin Wolf
2020-08-17 10:13   ` Max Reitz
2020-08-19 19:14   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 06/22] qemu-nbd: Use raw block driver for --offset Kevin Wolf
2020-08-17 10:56   ` Max Reitz
2020-08-17 11:41   ` Max Reitz
2020-08-17 17:19   ` Nir Soffer
2020-08-18  8:47     ` Kevin Wolf
2020-08-18  9:05       ` Nir Soffer
2020-08-19 19:33   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 07/22] block/export: Remove magic from block-export-add Kevin Wolf
2020-08-17 11:41   ` Max Reitz
2020-08-17 12:49     ` Kevin Wolf
2020-08-17 13:22       ` Max Reitz
2020-08-19 19:50   ` Eric Blake
2020-08-20 11:05     ` Kevin Wolf
2020-08-20 14:41       ` Eric Blake
2020-08-20 15:28         ` Peter Krempa
2020-08-13 16:29 ` [RFC PATCH 08/22] nbd: Add max-connections to nbd-server-start Kevin Wolf
2020-08-17 12:37   ` Max Reitz
2020-08-17 13:01     ` Kevin Wolf
2020-08-19 20:00   ` Eric Blake
2020-08-20 11:12     ` Kevin Wolf
2020-08-13 16:29 ` [RFC PATCH 09/22] nbd: Add writethrough to block-export-add Kevin Wolf
2020-08-17 12:56   ` Max Reitz
2020-08-17 13:13     ` Kevin Wolf
2020-08-17 13:51       ` Max Reitz
2020-08-17 14:32         ` Kevin Wolf
2020-08-17 15:35           ` Max Reitz
2020-08-19 20:05     ` Eric Blake
2020-08-19 20:13   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 10/22] nbd: Remove NBDExport.close callback Kevin Wolf
2020-08-17 14:02   ` Max Reitz
2020-08-19 20:17   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 11/22] qemu-nbd: Use blk_exp_add() to create the export Kevin Wolf
2020-08-17 14:27   ` Max Reitz
2020-08-17 14:38     ` Max Reitz
2020-08-17 15:01     ` Kevin Wolf
2020-08-19 20:35   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 12/22] nbd/server: Simplify export shutdown Kevin Wolf
2020-08-17 14:32   ` Max Reitz
2020-08-19 20:45   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 13/22] block/export: Move refcount from NBDExport to BlockExport Kevin Wolf
2020-08-17 14:49   ` Max Reitz
2020-08-19 20:58   ` Eric Blake
2020-08-20 14:15     ` Kevin Wolf
2020-08-13 16:29 ` [RFC PATCH 14/22] block/export: Move AioContext " Kevin Wolf
2020-08-17 14:56   ` Max Reitz
2020-08-17 15:22     ` Kevin Wolf
2020-08-17 15:47       ` Max Reitz
2020-08-13 16:29 ` [RFC PATCH 15/22] block/export: Move device to BlockExportOptions Kevin Wolf
2020-08-17 15:13   ` Max Reitz
2020-08-17 15:27     ` Kevin Wolf
2020-08-17 15:49       ` Max Reitz
2020-08-19 21:13   ` Eric Blake
2020-08-13 16:29 ` [RFC PATCH 16/22] block/export: Allocate BlockExport in blk_exp_add() Kevin Wolf
2020-08-18 14:25   ` Max Reitz
2020-08-13 16:29 ` [RFC PATCH 17/22] block/export: Add blk_exp_close_all(_type) Kevin Wolf
2020-08-18 15:00   ` Max Reitz
2020-08-13 16:29 ` [RFC PATCH 18/22] block/export: Add 'id' option to block-export-add Kevin Wolf
2020-08-18 15:08   ` Max Reitz
2020-08-13 16:29 ` [RFC PATCH 19/22] block/export: Move strong user reference to block_exports Kevin Wolf
2020-08-19  8:35   ` Max Reitz
2020-08-19 11:56   ` Max Reitz
2020-08-19 14:23     ` Kevin Wolf
2020-08-19 14:48       ` Max Reitz
2020-08-13 16:29 ` Kevin Wolf [this message]
2020-08-19  9:54   ` [RFC PATCH 20/22] block/export: Add block-export-del Max Reitz
2020-08-13 16:29 ` [RFC PATCH 21/22] block/export: Move blk to BlockExport Kevin Wolf
2020-08-19 10:53   ` Max Reitz
2020-08-13 16:29 ` [RFC PATCH 22/22] block/export: Add query-block-exports Kevin Wolf
2020-08-19 11:04   ` Max Reitz
2020-08-19 12:04     ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200813162935.210070-21-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).