On 23 Apr 2016, at 00:40, Eric Blake <ebl...@redhat.com> wrote:

> 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 <ebl...@redhat.com>

Reviewed-by: Alex Bligh <a...@alex.org.uk>

> ---
> 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
> -- 
> 2.5.5
> 
> 

-- 
Alex Bligh





Reply via email to