qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 29/29] qmp: add NBD server commands
Date: Fri, 19 Oct 2012 15:32:08 +0200	[thread overview]
Message-ID: <1350653528-5834-30-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1350653528-5834-1-git-send-email-pbonzini@redhat.com>

Adding an NBD server inside QEMU is trivial, since all the logic is
in nbd.c and can be shared easily between qemu-nbd and QEMU itself.
The main difference is that qemu-nbd serves a single unnamed export,
while QEMU serves named exports.

Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile.objs    |   2 +-
 blockdev-nbd.c   | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qapi-schema.json |  43 ++++++++++++++++++++
 qmp-commands.hx  |  16 ++++++++
 4 file modificati, 179 inserzioni(+). 1 rimozione(-)
 create mode 100644 blockdev-nbd.c

diff --git a/Makefile.objs b/Makefile.objs
index ca67885..9eca179 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -61,7 +61,7 @@ endif
 # suppress *all* target specific code in case of system emulation, i.e. a
 # single QEMU executable should support all CPUs and machines.
 
-common-obj-y = $(block-obj-y) blockdev.o block/
+common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
 common-obj-y += net.o net/
 common-obj-y += qom/
 common-obj-y += readline.o console.o cursor.o
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
new file mode 100644
index 0000000..8031813
--- /dev/null
+++ b/blockdev-nbd.c
@@ -0,0 +1,119 @@
+/*
+ * Serving QEMU block devices via NBD
+ *
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "blockdev.h"
+#include "hw/block-common.h"
+#include "monitor.h"
+#include "qerror.h"
+#include "sysemu.h"
+#include "qmp-commands.h"
+#include "trace.h"
+#include "nbd.h"
+#include "qemu_socket.h"
+
+static int server_fd = -1;
+
+static void nbd_accept(void *opaque)
+{
+    struct sockaddr_in addr;
+    socklen_t addr_len = sizeof(addr);
+
+    int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
+    if (fd >= 0) {
+        nbd_client_new(NULL, fd, nbd_client_put);
+    }
+}
+
+void qmp_nbd_server_start(SocketAddress *addr, Error **errp)
+{
+    if (server_fd != -1) {
+        error_setg(errp, "NBD server already running");
+        return;
+    }
+
+    server_fd = socket_listen(addr, errp);
+    if (server_fd != -1) {
+        qemu_set_fd_handler2(server_fd, NULL, nbd_accept, NULL, NULL);
+    }
+}
+
+/* Hook into the BlockDriverState notifiers to close the export when
+ * the file is closed.
+ */
+typedef struct NBDCloseNotifier {
+    Notifier n;
+    NBDExport *exp;
+    QTAILQ_ENTRY(NBDCloseNotifier) next;
+} NBDCloseNotifier;
+
+static QTAILQ_HEAD(, NBDCloseNotifier) close_notifiers =
+    QTAILQ_HEAD_INITIALIZER(close_notifiers);
+
+static void nbd_close_notifier(Notifier *n, void *data)
+{
+    NBDCloseNotifier *cn = DO_UPCAST(NBDCloseNotifier, n, n);
+
+    notifier_remove(&cn->n);
+    QTAILQ_REMOVE(&close_notifiers, cn, next);
+
+    nbd_export_close(cn->exp);
+    nbd_export_put(cn->exp);
+    g_free(cn);
+}
+
+static void nbd_server_put_ref(NBDExport *exp)
+{
+    BlockDriverState *bs = nbd_export_get_blockdev(exp);
+    drive_put_ref(drive_get_by_blockdev(bs));
+}
+
+void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
+                        Error **errp)
+{
+    BlockDriverState *bs;
+    NBDExport *exp;
+    NBDCloseNotifier *n;
+
+    if (nbd_export_find(device)) {
+        error_setg(errp, "NBD server already exporting device '%s'", device);
+        return;
+    }
+
+    bs = bdrv_find(device);
+    if (!bs) {
+        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+        return;
+    }
+
+    exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY,
+                         nbd_server_put_ref);
+
+    nbd_export_set_name(exp, device);
+    drive_get_ref(drive_get_by_blockdev(bs));
+
+    n = g_malloc0(sizeof(NBDCloseNotifier));
+    n->n.notify = nbd_close_notifier;
+    n->exp = exp;
+    bdrv_add_close_notifier(bs, &n->n);
+    QTAILQ_INSERT_TAIL(&close_notifiers, n, next);
+}
+
+void qmp_nbd_server_stop(Error **errp)
+{
+    while (!QTAILQ_EMPTY(&close_notifiers)) {
+        NBDCloseNotifier *cn = QTAILQ_FIRST(&close_notifiers);
+        nbd_close_notifier(&cn->n, nbd_export_get_blockdev(cn->exp));
+    }
+
+    qemu_set_fd_handler2(server_fd, NULL, NULL, NULL, NULL);
+    close(server_fd);
+    server_fd = -1;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index a92a33b..4451588 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2849,3 +2849,46 @@
 # Since: 0.14.0
 ##
 { 'command': 'screendump', 'data': {'filename': 'str'} }
+
+##
+# @nbd-server-start:
+#
+# Start an NBD server listening on the given host and port.  Block
+# devices can then be exported using @nbd-server-add.  The NBD
+# server will present them as named exports; for example, another
+# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
+#
+# @addr: Address on which to listen.
+#
+# Returns: error if the server is already running.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-start',
+  'data': { 'addr': 'SocketAddress' } }
+
+##
+# @nbd-server-add:
+#
+# Export a device to QEMU's embedded NBD server.
+#
+# @device: Block device to be exported
+#
+# @writable: Whether clients should be able to write to the device via the
+#     NBD connection (default false). #optional
+#
+# Returns: error if the device is already marked for export.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-add', 'data': {'device': 'str', '*writable': 'bool'} }
+
+##
+# @nbd-server-stop:
+#
+# Stop QEMU's embedded NBD server, and unregister all devices previously
+# added via @nbd-server-add.
+#
+# Since: 1.3.0
+##
+{ 'command': 'nbd-server-stop' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 2f8477e..8b40902 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2543,6 +2543,22 @@ EQMP
     },
 
     {
+        .name       = "nbd-server-start",
+        .args_type  = "addr:q",
+        .mhandler.cmd_new = qmp_marshal_input_nbd_server_start,
+    },
+    {
+        .name       = "nbd-server-add",
+        .args_type  = "device:B,writable:b?",
+        .mhandler.cmd_new = qmp_marshal_input_nbd_server_add,
+    },
+    {
+        .name       = "nbd-server-stop",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_nbd_server_stop,
+    },
+
+    {
         .name       = "change-vnc-password",
         .args_type  = "password:s",
         .mhandler.cmd_new = qmp_marshal_input_change_vnc_password,
-- 
1.7.12.1

  parent reply	other threads:[~2012-10-19 13:35 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-19 13:31 [Qemu-devel] [PULL 00/29] qemu-sockets error propagation + NBD server Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 01/29] error: add error_set_errno and error_setg_errno Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 02/29] qemu-sockets: add Error ** to all functions Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 03/29] qemu-sockets: unix_listen and unix_connect are portable Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 04/29] qemu-sockets: add nonblocking connect for Unix sockets Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 05/29] migration: avoid using error_is_set and thus relying on errp != NULL Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 06/29] migration: centralize call to migrate_fd_error() Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 07/29] migration: use qemu-sockets to establish Unix sockets Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 08/29] migration (outgoing): add error propagation for all protocols Paolo Bonzini
2012-10-22 15:52   ` Markus Armbruster
2012-10-23 11:27     ` Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 09/29] migration (incoming): add error propagation to fd and exec protocols Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 10/29] qemu-char: ask and print error information from qemu-sockets Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 11/29] nbd: " Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 12/29] qemu-ga: " Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 13/29] vnc: avoid Yoda conditionals Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 14/29] vnc: introduce a single label for error returns Paolo Bonzini
2012-10-22 15:49   ` Markus Armbruster
2012-10-23 11:32     ` Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 15/29] vnc: reorganize code for reverse mode Paolo Bonzini
2012-10-22 15:39   ` Markus Armbruster
2012-10-19 13:31 ` [Qemu-devel] [PATCH 16/29] vnc: add error propagation to vnc_display_open Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 17/29] qemu-sockets: include strerror or gai_strerror output in error messages Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 18/29] qemu-sockets: add error propagation to inet_connect_addr Paolo Bonzini
2012-10-22 15:53   ` Markus Armbruster
2012-10-19 13:31 ` [Qemu-devel] [PATCH 19/29] qemu-sockets: add error propagation to inet_dgram_opts Paolo Bonzini
2012-10-19 13:31 ` [Qemu-devel] [PATCH 20/29] qemu-sockets: add error propagation to inet_parse Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 21/29] qemu-sockets: add error propagation to Unix socket functions Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 22/29] vnc: drop QERR_VNC_SERVER_FAILED Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 23/29] build: add QAPI files to the tools Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 24/29] qapi: add socket address types Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 25/29] qemu-sockets: return InetSocketAddress from inet_parse Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 26/29] qemu-sockets: add socket_listen, socket_connect, socket_parse Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 27/29] block: prepare code for adding block notifiers Paolo Bonzini
2012-10-19 13:32 ` [Qemu-devel] [PATCH 28/29] block: add close notifiers Paolo Bonzini
2012-10-19 13:32 ` Paolo Bonzini [this message]
2012-10-22 15:59 ` [Qemu-devel] [PULL 00/29] qemu-sockets error propagation + NBD server Markus Armbruster
2012-10-22 19:53 ` Anthony Liguori
2012-10-23 12:34   ` Paolo Bonzini
2012-10-23 15:27     ` Paolo Bonzini
2012-10-23 21:24       ` Paolo Bonzini
2012-10-26 15:33 ` Anthony Liguori

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=1350653528-5834-30-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --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).