From patchwork Fri Apr 22 23:40:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 8916301 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F13C6BF29F for ; Fri, 22 Apr 2016 23:46:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1BAB92020F for ; Fri, 22 Apr 2016 23:46:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F3D7D201C7 for ; Fri, 22 Apr 2016 23:46:11 +0000 (UTC) Received: from localhost ([::1]:41765 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atkm3-0004ra-92 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 22 Apr 2016 19:46:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45028) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atkhZ-0003hn-Qt for qemu-devel@nongnu.org; Fri, 22 Apr 2016 19:41:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1atkhY-0005LB-8H for qemu-devel@nongnu.org; Fri, 22 Apr 2016 19:41:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55224) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1atkhS-0005IQ-TD; Fri, 22 Apr 2016 19:41:27 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7BD8AC05E16A; Fri, 22 Apr 2016 23:41:26 +0000 (UTC) Received: from red.redhat.com (ovpn-113-21.phx2.redhat.com [10.3.113.21]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u3MNfHWv028475; Fri, 22 Apr 2016 19:41:25 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Fri, 22 Apr 2016 17:40:16 -0600 Message-Id: <1461368452-10389-9-git-send-email-eblake@redhat.com> In-Reply-To: <1461368452-10389-1-git-send-email-eblake@redhat.com> References: <1461368452-10389-1-git-send-email-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 08/44] nbd: Add qemu-nbd -D for human-readable description X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Paolo Bonzini , alex@alex.org.uk, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The NBD protocol allows servers to advertise a human-readable description alongside an export name during NBD_OPT_LIST. Add an option to pass through the user's string to the NBD client. Doing this also makes it easier to test commit 200650d4, which is the client counterpart of receiving the description. Signed-off-by: Eric Blake Reviewed-by: Alex Bligh --- include/block/nbd.h | 1 + nbd/nbd-internal.h | 5 +++-- nbd/server.c | 34 ++++++++++++++++++++++++++-------- qemu-nbd.c | 12 +++++++++++- qemu-nbd.texi | 5 ++++- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 134f117..3e2d76b 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -107,6 +107,7 @@ BlockBackend *nbd_export_get_blockdev(NBDExport *exp); NBDExport *nbd_export_find(const char *name); void nbd_export_set_name(NBDExport *exp, const char *name); +void nbd_export_set_description(NBDExport *exp, const char *description); void nbd_export_close_all(void); void nbd_client_new(NBDExport *exp, diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index 3791535..035ead4 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -103,9 +103,10 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) return nbd_wr_syncv(ioc, &iov, 1, 0, size, true); } -static inline ssize_t write_sync(QIOChannel *ioc, void *buffer, size_t size) +static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer, + size_t size) { - struct iovec iov = { .iov_base = buffer, .iov_len = size }; + struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size }; return nbd_wr_syncv(ioc, &iov, 1, 0, size, false); } diff --git a/nbd/server.c b/nbd/server.c index 31fc9cf..aa252a4 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -61,6 +61,7 @@ struct NBDExport { BlockBackend *blk; char *name; + char *description; off_t dev_offset; off_t size; uint16_t nbdflags; @@ -128,7 +129,8 @@ static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) } -static ssize_t nbd_negotiate_write(QIOChannel *ioc, void *buffer, size_t size) +static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer, + size_t size) { ssize_t ret; guint watch; @@ -224,11 +226,15 @@ static int nbd_negotiate_send_rep(QIOChannel *ioc, uint32_t type, uint32_t opt) static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) { - uint64_t magic, name_len; + uint64_t magic; + size_t name_len, desc_len; uint32_t opt, type, len; + const char *name = exp->name ? exp->name : ""; + const char *desc = exp->description ? exp->description : ""; - TRACE("Advertising export name '%s'", exp->name ? exp->name : ""); - name_len = strlen(exp->name); + TRACE("Advertising export name '%s' description '%s'", name, desc); + name_len = strlen(name); + desc_len = strlen(desc); magic = cpu_to_be64(NBD_REP_MAGIC); if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { LOG("write failed (magic)"); @@ -244,18 +250,22 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) LOG("write failed (reply type)"); return -EINVAL; } - len = cpu_to_be32(name_len + sizeof(len)); + len = cpu_to_be32(name_len + desc_len + sizeof(len)); if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { LOG("write failed (length)"); return -EINVAL; } len = cpu_to_be32(name_len); if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { - LOG("write failed (length)"); + LOG("write failed (name length)"); return -EINVAL; } - if (nbd_negotiate_write(ioc, exp->name, name_len) != name_len) { - LOG("write failed (buffer)"); + if (nbd_negotiate_write(ioc, name, name_len) != name_len) { + LOG("write failed (name buffer)"); + return -EINVAL; + } + if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) { + LOG("write failed (description buffer)"); return -EINVAL; } return 0; @@ -877,6 +887,12 @@ void nbd_export_set_name(NBDExport *exp, const char *name) nbd_export_put(exp); } +void nbd_export_set_description(NBDExport *exp, const char *description) +{ + g_free(exp->description); + exp->description = g_strdup(description); +} + void nbd_export_close(NBDExport *exp) { NBDClient *client, *next; @@ -886,6 +902,7 @@ void nbd_export_close(NBDExport *exp) client_close(client); } nbd_export_set_name(exp, NULL); + nbd_export_set_description(exp, NULL); nbd_export_put(exp); } @@ -904,6 +921,7 @@ void nbd_export_put(NBDExport *exp) if (--exp->refcount == 0) { assert(exp->name == NULL); + assert(exp->description == NULL); if (exp->close) { exp->close(exp); diff --git a/qemu-nbd.c b/qemu-nbd.c index 71bfdeb..a85e98f 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -77,6 +77,7 @@ static void usage(const char *name) " -t, --persistent don't exit on the last connection\n" " -v, --verbose display extra debugging information\n" " -x, --export-name=NAME expose export by name\n" +" -D, --description=TEXT with -x, also export a human-readable description\n" "\n" "Exposing part of the image:\n" " -o, --offset=OFFSET offset into the image\n" @@ -464,7 +465,7 @@ int main(int argc, char **argv) off_t fd_size; QemuOpts *sn_opts = NULL; const char *sn_id_or_name = NULL; - const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:"; + const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:D:"; struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -490,6 +491,7 @@ int main(int argc, char **argv) { "verbose", no_argument, NULL, 'v' }, { "object", required_argument, NULL, QEMU_NBD_OPT_OBJECT }, { "export-name", required_argument, NULL, 'x' }, + { "description", required_argument, NULL, 'D' }, { "tls-creds", required_argument, NULL, QEMU_NBD_OPT_TLSCREDS }, { "image-opts", no_argument, NULL, QEMU_NBD_OPT_IMAGE_OPTS }, { NULL, 0, NULL, 0 } @@ -509,6 +511,7 @@ int main(int argc, char **argv) BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF; QDict *options = NULL; const char *export_name = NULL; + const char *export_description = NULL; const char *tlscredsid = NULL; bool imageOpts = false; bool writethrough = true; @@ -672,6 +675,9 @@ int main(int argc, char **argv) case 'x': export_name = optarg; break; + case 'D': + export_description = optarg; + break; case 'v': verbose = 1; break; @@ -899,7 +905,11 @@ int main(int argc, char **argv) } if (export_name) { nbd_export_set_name(exp, export_name); + nbd_export_set_description(exp, export_description); newproto = true; + } else if (export_description) { + error_report("Export description requires an export name"); + exit(EXIT_FAILURE); } server_ioc = qio_channel_socket_new(); diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 9f23343..923de74 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -79,9 +79,12 @@ Disconnect the device @var{dev} Allow up to @var{num} clients to share the device (default @samp{1}) @item -t, --persistent Don't exit on the last connection -@item -x NAME, --export-name=NAME +@item -x, --export-name=@var{name} Set the NBD volume export name. This switches the server to use the new style NBD protocol negotiation +@item -D, --description=@var{description} +Set the NBD volume export description, as a human-readable +string. Requires the use of @option{-x} @item --tls-creds=ID Enable mandatory TLS encryption for the server by setting the ID of the TLS credentials object previously created with the --object