From: Luiz Capitulino <lcapitulino@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 8/9] qmp: add NBD server commands
Date: Tue, 2 Oct 2012 09:37:51 -0300 [thread overview]
Message-ID: <20121002093751.1506f8aa@doriath.home> (raw)
In-Reply-To: <1349103144-6827-9-git-send-email-pbonzini@redhat.com>
On Mon, 1 Oct 2012 16:52:23 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:
> 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.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Luiz Capitulino <lcapitulino@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 124f783..40384ff 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
> +common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o
> 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 b443a99..229421d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2697,3 +2697,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 36e08d9..c394af0 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -2503,6 +2503,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,
next prev parent reply other threads:[~2012-10-02 12:54 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-01 14:52 [Qemu-devel] [PATCH v2 0/9] Embedded NBD server Paolo Bonzini
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 1/9] build: add QAPI files to the tools Paolo Bonzini
2012-10-02 12:31 ` Luiz Capitulino
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 2/9] qapi: add socket address types Paolo Bonzini
2012-10-01 23:56 ` Eric Blake
2012-10-02 9:00 ` Paolo Bonzini
2012-10-02 11:39 ` Eric Blake
2012-10-02 12:27 ` Luiz Capitulino
2012-10-02 14:24 ` Paolo Bonzini
2012-10-02 15:27 ` Luiz Capitulino
2012-10-02 15:31 ` Paolo Bonzini
2012-10-02 12:32 ` Luiz Capitulino
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 3/9] qemu-sockets: add error propagation to inet_parse Paolo Bonzini
2012-10-02 12:34 ` Luiz Capitulino
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 4/9] qemu-sockets: add error propagation to Unix socket functions Paolo Bonzini
2012-10-01 17:17 ` Luiz Capitulino
2012-10-01 19:07 ` Paolo Bonzini
2012-10-01 23:05 ` Luiz Capitulino
2012-10-02 6:09 ` Paolo Bonzini
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 5/9] qemu-sockets: return IPSocketAddress from inet_parse Paolo Bonzini
2012-10-02 12:36 ` Luiz Capitulino
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 6/9] qemu-sockets: add socket_listen, socket_connect, socket_parse Paolo Bonzini
2012-10-02 12:37 ` Luiz Capitulino
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 7/9] block: add close notifiers Paolo Bonzini
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 8/9] qmp: add NBD server commands Paolo Bonzini
2012-10-02 2:50 ` Eric Blake
2012-10-02 12:37 ` Luiz Capitulino [this message]
2012-10-31 11:23 ` Christoph Hellwig
2012-10-31 12:46 ` Paolo Bonzini
2012-10-31 13:01 ` Christoph Hellwig
2012-10-01 14:52 ` [Qemu-devel] [PATCH v2 9/9] hmp: " Paolo Bonzini
2012-10-02 12:38 ` Luiz Capitulino
2012-10-01 18:08 ` [Qemu-devel] [PATCH v2 0/9] Embedded NBD server Luiz Capitulino
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=20121002093751.1506f8aa@doriath.home \
--to=lcapitulino@redhat.com \
--cc=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).