All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support
@ 2014-06-07  0:32 Hani Benhabiles
  2014-06-07  0:32 ` [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients Hani Benhabiles
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Hani Benhabiles @ 2014-06-07  0:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, stefanha

Compared to v2:
* 1/2: Handle options in loop. Handle NBD_OPT_ABORT. Add link to documentation.
  Improve commit message.
* 2/2: Fix return value in NBD_OPT_LIST case. Rename nbd_send_list() function to
  nbd_handle_list().
* Remove patch 3/3 from v2. Applied separately by Paolo.

Hani Benhabiles (2):
  nbd: Handle fixed new-style clients.
  nbd: Handle NBD_OPT_LIST option.

 include/block/nbd.h |  11 +++
 nbd.c               | 200 +++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 170 insertions(+), 41 deletions(-)

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients.
  2014-06-07  0:32 [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Hani Benhabiles
@ 2014-06-07  0:32 ` Hani Benhabiles
  2014-06-07  0:32 ` [Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option Hani Benhabiles
  2014-06-09  9:12 ` [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Hani Benhabiles @ 2014-06-07  0:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, stefanha

When this flag is set, the server tells the client that it can send another
option if the server received a request with an option that it doesn't
understand instead of directly closing the connection.

Also add link to the most up-to-date documentation.

Signed-off-by: Hani Benhabiles <hani@linux.com>
---
 include/block/nbd.h |   9 ++++
 nbd.c               | 143 ++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 109 insertions(+), 43 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 79502a0..561b70c 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -45,6 +45,15 @@ struct nbd_reply {
 #define NBD_FLAG_ROTATIONAL     (1 << 4)        /* Use elevator algorithm - rotational media */
 #define NBD_FLAG_SEND_TRIM      (1 << 5)        /* Send TRIM (discard) */
 
+/* New-style global flags. */
+#define NBD_FLAG_FIXED_NEWSTYLE     (1 << 0)    /* Fixed newstyle protocol. */
+
+/* New-style client flags. */
+#define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)    /* Fixed newstyle protocol. */
+
+/* Reply types. */
+#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 e0d032c..7cee1ef 100644
--- a/nbd.c
+++ b/nbd.c
@@ -56,7 +56,11 @@
             __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
 } while(0)
 
-/* This is all part of the "official" NBD API */
+/* This is all part of the "official" NBD API.
+ *
+ * The most up-to-date documentation is available at:
+ * https://github.com/yoe/nbd/blob/master/doc/proto.txt
+ */
 
 #define NBD_REQUEST_SIZE        (4 + 4 + 8 + 8 + 4)
 #define NBD_REPLY_SIZE          (4 + 4 + 8)
@@ -64,6 +68,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 +82,8 @@
 #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)
 
 /* Definitions for opaque data types */
 
@@ -215,53 +221,44 @@ 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;
+    uint32_t len;
 
-    /* Client sends:
-        [ 0 ..   3]   reserved (0)
-        [ 4 ..  11]   NBD_OPTS_MAGIC
-        [12 ..  15]   NBD_OPT_EXPORT_NAME
-        [16 ..  19]   length
-        [20 ..  xx]   export name (length bytes)
-     */
-
-    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 reserved");
-    if (tmp != 0) {
-        LOG("Bad reserved 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 reserved");
-    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;
-    }
-    TRACE("Checking option");
-    if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
-        LOG("Bad option received");
-        goto fail;
-    }
+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;
@@ -286,13 +283,70 @@ static int nbd_receive_options(NBDClient *client)
 
     QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
     nbd_export_get(client->exp);
-
-    TRACE("Option negotiation succeeded.");
     rc = 0;
 fail:
     return rc;
 }
 
+static int nbd_receive_options(NBDClient *client)
+{
+    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");
+            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");
+            return -EINVAL;
+        }
+
+        if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+            LOG("read failed");
+            return -EINVAL;
+        }
+        TRACE("Checking opts magic");
+        if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
+            LOG("Bad magic received");
+            return -EINVAL;
+        }
+
+        if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+            LOG("read failed");
+            return -EINVAL;
+        }
+
+        TRACE("Checking option");
+        switch (be32_to_cpu(tmp)) {
+        case NBD_OPT_ABORT:
+            return 1;
+
+        case NBD_OPT_EXPORT_NAME:
+            return nbd_handle_export_name(client);
+
+        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;
+        }
+    }
+}
+
 static int nbd_send_negotiate(NBDClient *client)
 {
     int csock = client->sock;
@@ -333,6 +387,7 @@ static int nbd_send_negotiate(NBDClient *client)
         cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
     } else {
         cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);
+        cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE);
     }
 
     if (client->exp) {
@@ -349,6 +404,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);
@@ -1173,7 +1230,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;
     }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option.
  2014-06-07  0:32 [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Hani Benhabiles
  2014-06-07  0:32 ` [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients Hani Benhabiles
@ 2014-06-07  0:32 ` Hani Benhabiles
  2014-06-09  9:12 ` [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Hani Benhabiles @ 2014-06-07  0:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, stefanha

Signed-off-by: Hani Benhabiles <hani@linux.com>
---
 include/block/nbd.h |  2 ++
 nbd.c               | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 561b70c..fd7e057 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -52,6 +52,8 @@ struct nbd_reply {
 #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
diff --git a/nbd.c b/nbd.c
index 7cee1ef..5d524b8 100644
--- a/nbd.c
+++ b/nbd.c
@@ -84,6 +84,7 @@
 
 #define NBD_OPT_EXPORT_NAME     (1)
 #define NBD_OPT_ABORT           (2)
+#define NBD_OPT_LIST            (3)
 
 /* Definitions for opaque data types */
 
@@ -249,6 +250,60 @@ static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
     return 0;
 }
 
+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;
+     }
+    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_handle_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;
@@ -330,6 +385,12 @@ static int nbd_receive_options(NBDClient *client)
 
         TRACE("Checking option");
         switch (be32_to_cpu(tmp)) {
+        case NBD_OPT_LIST:
+            if (nbd_handle_list(client) < 0) {
+                return -EINVAL;
+            }
+            return 1;
+
         case NBD_OPT_ABORT:
             return 1;
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support
  2014-06-07  0:32 [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Hani Benhabiles
  2014-06-07  0:32 ` [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients Hani Benhabiles
  2014-06-07  0:32 ` [Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option Hani Benhabiles
@ 2014-06-09  9:12 ` Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2014-06-09  9:12 UTC (permalink / raw)
  To: Hani Benhabiles, qemu-devel; +Cc: stefanha

Il 07/06/2014 02:32, Hani Benhabiles ha scritto:
> Compared to v2:
> * 1/2: Handle options in loop. Handle NBD_OPT_ABORT. Add link to documentation.
>   Improve commit message.
> * 2/2: Fix return value in NBD_OPT_LIST case. Rename nbd_send_list() function to
>   nbd_handle_list().
> * Remove patch 3/3 from v2. Applied separately by Paolo.
>
> Hani Benhabiles (2):
>   nbd: Handle fixed new-style clients.
>   nbd: Handle NBD_OPT_LIST option.
>
>  include/block/nbd.h |  11 +++
>  nbd.c               | 200 +++++++++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 170 insertions(+), 41 deletions(-)
>

Applied, thanks!

Paolo

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-06-09  9:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-07  0:32 [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Hani Benhabiles
2014-06-07  0:32 ` [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients Hani Benhabiles
2014-06-07  0:32 ` [Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option Hani Benhabiles
2014-06-09  9:12 ` [Qemu-devel] [PATCH 0/2] nbd: Add exports listing support Paolo Bonzini

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.