From: Hani Benhabiles <kroosec@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kwolf@redhat.com, famz@redhat.com, qemu-devel@nongnu.org,
stefanha@redhat.com, mreitz@redhat.com
Subject: Re: [Qemu-devel] [PATCH 2/3] nbd: Add exports listing support.
Date: Wed, 4 Jun 2014 23:35:52 +0100 [thread overview]
Message-ID: <20140604223552.GB7620@Inspiron-3521> (raw)
In-Reply-To: <538DB343.1060006@redhat.com>
On Tue, Jun 03, 2014 at 01:36:35PM +0200, Paolo Bonzini wrote:
> 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.
>
Ack.
> >+ 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.
>
Alright, I will resend, making the changes you and Stefan suggested.
Thanks.
prev parent reply other threads:[~2014-06-04 22: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 ` [Qemu-devel] [PATCH 2/3] nbd: Add exports listing support Paolo Bonzini
2014-06-04 22:35 ` Hani Benhabiles [this message]
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=20140604223552.GB7620@Inspiron-3521 \
--to=kroosec@gmail.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=pbonzini@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.