qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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,

  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).