All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Hani Benhabiles <kroosec@gmail.com>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, famz@redhat.com, stefanha@redhat.com,
	mreitz@redhat.com
Subject: Re: [Qemu-devel] [PATCH 2/3] nbd: Add exports listing support.
Date: Tue, 03 Jun 2014 13:36:35 +0200	[thread overview]
Message-ID: <538DB343.1060006@redhat.com> (raw)
In-Reply-To: <1401572382-11667-3-git-send-email-kroosec@gmail.com>

Il 31/05/2014 23:39, Hani Benhabiles ha scritto:
> This is added by handling the NBD_OPT_LIST and NBD_OPT_ABORT options.
>
> NBD_REP_ERR_UNSUP is also sent for unknown NBD option values.
>
> Signed-off-by: Hani Benhabiles <hani@linux.com>
> ---
>  include/block/nbd.h |   5 ++
>  nbd.c               | 197 +++++++++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 162 insertions(+), 40 deletions(-)
>
> diff --git a/include/block/nbd.h b/include/block/nbd.h
> index 95d52ab..fd7e057 100644
> --- a/include/block/nbd.h
> +++ b/include/block/nbd.h
> @@ -51,6 +51,11 @@ struct nbd_reply {
>  /* New-style client flags. */
>  #define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)    /* Fixed newstyle protocol. */
>
> +/* Reply types. */
> +#define NBD_REP_ACK             (1)             /* Data sending finished. */
> +#define NBD_REP_SERVER          (2)             /* Export description. */
> +#define NBD_REP_ERR_UNSUP       ((1 << 31) | 1) /* Unknown option. */
> +
>  #define NBD_CMD_MASK_COMMAND	0x0000ffff
>  #define NBD_CMD_FLAG_FUA	(1 << 16)
>
> diff --git a/nbd.c b/nbd.c
> index aa2e552..012e5da 100644
> --- a/nbd.c
> +++ b/nbd.c
> @@ -64,6 +64,7 @@
>  #define NBD_REPLY_MAGIC         0x67446698
>  #define NBD_OPTS_MAGIC          0x49484156454F5054LL
>  #define NBD_CLIENT_MAGIC        0x0000420281861253LL
> +#define NBD_REP_MAGIC           0x3e889045565a9LL
>
>  #define NBD_SET_SOCK            _IO(0xab, 0)
>  #define NBD_SET_BLKSIZE         _IO(0xab, 1)
> @@ -77,7 +78,9 @@
>  #define NBD_SET_TIMEOUT         _IO(0xab, 9)
>  #define NBD_SET_FLAGS           _IO(0xab, 10)
>
> -#define NBD_OPT_EXPORT_NAME     (1 << 0)
> +#define NBD_OPT_EXPORT_NAME     (1)
> +#define NBD_OPT_ABORT           (2)
> +#define NBD_OPT_LIST            (3)
>
>  /* Definitions for opaque data types */
>
> @@ -215,54 +218,98 @@ static ssize_t write_sync(int fd, void *buffer, size_t size)
>
>  */
>
> -static int nbd_receive_options(NBDClient *client)
> +static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
>  {
> -    int csock = client->sock;
> -    char name[256];
> -    uint32_t tmp, length;
>      uint64_t magic;
> -    int rc;
> -
> -    /* Client sends:
> -        [ 0 ..   3]   client flags
> -        [ 4 ..  11]   NBD_OPTS_MAGIC
> -        [12 ..  15]   NBD_OPT_EXPORT_NAME
> -        [16 ..  19]   length
> -        [20 ..  xx]   export name (length bytes)
> -     */
> +    uint32_t len;
>
> -    rc = -EINVAL;
> -    if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> -        LOG("read failed");
> -        goto fail;
> +    magic = cpu_to_be64(NBD_REP_MAGIC);
> +    if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> +        LOG("write failed (rep magic)");
> +        return -EINVAL;
>      }
> -    TRACE("Checking client flags");
> -    tmp = be32_to_cpu(tmp);
> -    if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
> -        LOG("Bad client flags received");
> -        goto fail;
> +    opt = cpu_to_be32(opt);
> +    if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
> +        LOG("write failed (rep opt)");
> +        return -EINVAL;
>      }
> -
> -    if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> -        LOG("read failed");
> -        goto fail;
> +    type = cpu_to_be32(type);
> +    if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
> +        LOG("write failed (rep type)");
> +        return -EINVAL;
>      }
> -    TRACE("Checking opts magic");
> -    if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
> -        LOG("Bad magic received");
> -        goto fail;
> +    len = cpu_to_be32(0);
> +    if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
> +        LOG("write failed (rep data length)");
> +        return -EINVAL;
>      }
> +    return 0;
> +}
>
> -    if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> -        LOG("read failed");
> -        goto fail;
> +static int nbd_send_rep_list(int csock, NBDExport *exp)
> +{
> +    uint64_t magic, name_len;
> +    uint32_t opt, type, len;
> +
> +    name_len = strlen(exp->name);
> +    magic = cpu_to_be64(NBD_REP_MAGIC);
> +    if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> +        LOG("write failed (magic)");
> +        return -EINVAL;
>      }
> -    TRACE("Checking option");
> -    if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
> -        LOG("Bad option received");
> -        goto fail;
> +    opt = cpu_to_be32(NBD_OPT_LIST);
> +    if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
> +        LOG("write failed (opt)");
> +        return -EINVAL;
> +    }
> +    type = cpu_to_be32(NBD_REP_SERVER);
> +    if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
> +        LOG("write failed (reply type)");
> +        return -EINVAL;
> +    }
> +    len = cpu_to_be32(name_len + sizeof(len));
> +    if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
> +        LOG("write failed (length)");
> +        return -EINVAL;
> +    }
> +    len = cpu_to_be32(name_len);
> +    if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
> +        LOG("write failed (length)");
> +        return -EINVAL;
> +    }
> +    if (write_sync(csock, exp->name, name_len) != name_len) {
> +        LOG("write failed (buffer)");
> +        return -EINVAL;
> +    }
> +    return 0;
> +}
> +
> +static int nbd_send_list(NBDClient *client)
> +{
> +    int csock;
> +    NBDExport *exp;
> +
> +    csock = client->sock;
> +    /* For each export, send a NBD_REP_SERVER reply. */
> +    QTAILQ_FOREACH(exp, &exports, next) {
> +        if (nbd_send_rep_list(csock, exp)) {
> +            return -EINVAL;
> +        }
>      }
> +    /* Finish with a NBD_REP_ACK. */
> +    return nbd_send_rep(csock, NBD_REP_ACK, NBD_OPT_LIST);
> +}
> +
> +static int nbd_handle_export_name(NBDClient *client)
> +{
> +    int rc = -EINVAL, csock = client->sock;
> +    char name[256];
> +    uint32_t length;
>
> +    /* Client sends:
> +        [16 ..  19]   length
> +        [20 ..  xx]   export name (length bytes)
> +     */
>      if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
>          LOG("read failed");
>          goto fail;
> @@ -287,8 +334,76 @@ static int nbd_receive_options(NBDClient *client)
>
>      QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
>      nbd_export_get(client->exp);
> +    rc = 0;
> +fail:
> +    return rc;
> +}
> +
> +static int nbd_receive_options(NBDClient *client)
> +{
> +    int rc = -EINVAL;
>
> -    TRACE("Option negotiation succeeded.");
> +    while (1) {
> +        int csock = client->sock;
> +        uint32_t tmp;
> +        uint64_t magic;
> +
> +        /* Client sends:
> +            [ 0 ..   3]   client flags
> +            [ 4 ..  11]   NBD_OPTS_MAGIC
> +            [12 ..  15]   NBD option
> +            ...           Rest of request
> +        */
> +
> +        if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> +            LOG("read failed");
> +            goto fail;
> +        }
> +        TRACE("Checking client flags");
> +        tmp = be32_to_cpu(tmp);
> +        if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
> +            LOG("Bad client flags received");
> +            goto fail;
> +        }
> +
> +        if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> +            LOG("read failed");
> +            goto fail;
> +        }
> +        TRACE("Checking opts magic");
> +        if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
> +            LOG("Bad magic received");
> +            goto fail;
> +        }
> +
> +        if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> +            LOG("read failed");
> +            goto fail;
> +        }
> +
> +        TRACE("Checking option");
> +        switch (be32_to_cpu(tmp)) {
> +        case NBD_OPT_LIST:
> +            if (nbd_send_list(client) < 0) {
> +                return -EINVAL;
> +            }
> +            break;

You can just do "return nbd_send_list(client);" here.  You probably 
should also rename the function to nbd_handle_list.

> +        case NBD_OPT_ABORT:
> +            return 1;
> +
> +        case NBD_OPT_EXPORT_NAME:
> +            return nbd_handle_export_name(client);

Part of this patch belongs in patch 1.  This one should only add 
nbd_send_rep_list, nbd_handle_list and the NBD_OPT_LIST case.

Paolo

> +        default:
> +            tmp = be32_to_cpu(tmp);
> +            LOG("Unsupported option 0x%x", tmp);
> +            if (nbd_send_rep(client->sock, NBD_REP_ERR_UNSUP, tmp)) {
> +                return -EINVAL;
> +            }
> +            return 1;
> +        }
> +    }
>      rc = 0;
>  fail:
>      return rc;
> @@ -351,6 +466,8 @@ static int nbd_send_negotiate(NBDClient *client)
>          if (rc < 0) {
>              LOG("option negotiation failed");
>              goto fail;
> +        } else if (rc > 0) {
> +            goto fail;
>          }
>
>          assert ((client->exp->nbdflags & ~65535) == 0);
> @@ -1175,7 +1292,7 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
>      client->refcount = 1;
>      client->exp = exp;
>      client->sock = csock;
> -    if (nbd_send_negotiate(client) < 0) {
> +    if (nbd_send_negotiate(client)) {
>          g_free(client);
>          return NULL;
>      }
>

  parent reply	other threads:[~2014-06-03 11:36 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1401572382-11667-1-git-send-email-kroosec@gmail.com>
     [not found] ` <1401572382-11667-2-git-send-email-kroosec@gmail.com>
2014-06-02 12:32   ` [Qemu-devel] [PATCH 1/3] nbd: Handle fixed new-style clients Stefan Hajnoczi
2014-06-02 22:09     ` Hani Benhabiles
2014-06-04  8:01       ` Stefan Hajnoczi
     [not found] ` <1401572382-11667-4-git-send-email-kroosec@gmail.com>
2014-06-03 11:33   ` [Qemu-devel] [PATCH 3/3] nbd: Shutdown socket before closing Paolo Bonzini
2014-06-04 22:33     ` Hani Benhabiles
2014-06-05  1:55       ` Paolo Bonzini
2014-06-05  9:58         ` Hani Benhabiles
2014-06-05 10:31           ` Paolo Bonzini
     [not found] ` <1401572382-11667-3-git-send-email-kroosec@gmail.com>
2014-06-03 11:36   ` Paolo Bonzini [this message]
2014-06-04 22:35     ` [Qemu-devel] [PATCH 2/3] nbd: Add exports listing support Hani Benhabiles

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=538DB343.1060006@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=famz@redhat.com \
    --cc=kroosec@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.