From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43878) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wt4ZV-00081Z-TP for qemu-devel@nongnu.org; Fri, 06 Jun 2014 20:33:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wt4ZP-0000Sb-U6 for qemu-devel@nongnu.org; Fri, 06 Jun 2014 20:33:21 -0400 Received: from mail-wg0-x234.google.com ([2a00:1450:400c:c00::234]:33195) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wt4ZP-0000SR-Nm for qemu-devel@nongnu.org; Fri, 06 Jun 2014 20:33:15 -0400 Received: by mail-wg0-f52.google.com with SMTP id l18so3543481wgh.35 for ; Fri, 06 Jun 2014 17:33:14 -0700 (PDT) From: Hani Benhabiles Date: Sat, 7 Jun 2014 01:32:32 +0100 Message-Id: <1402101152-8927-3-git-send-email-kroosec@gmail.com> In-Reply-To: <1402101152-8927-1-git-send-email-kroosec@gmail.com> References: <1402101152-8927-1-git-send-email-kroosec@gmail.com> Subject: [Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, stefanha@redhat.com Signed-off-by: Hani Benhabiles --- 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