[Libguestfs] [nbdkit PATCH] nbd: Add vsock_cid= transport option

Richard W.M. Jones rjones at redhat.com
Fri Nov 22 20:43:59 UTC 2019


On Fri, Nov 22, 2019 at 02:13:59PM -0600, Eric Blake wrote:
> With new enough libnbd, we already support vsock by virtue of uri=;
> however, it's also nice to allow direct exposure of the
> nbd_connect_vsock() api.
> 
> Signed-off-by: Eric Blake <eblake at redhat.com>

Looks good, ACK.

Also re your question about the various uri_allow_* settings, it
sounds like we should implement those too.

Thanks,

Rich.

> 
> As with commit 7ce9feef, there is no easy way to add testsuite
> coverage for this.
> 
>  plugins/nbd/nbdkit-nbd-plugin.pod | 30 +++++++++-----
>  plugins/nbd/nbd.c                 | 65 ++++++++++++++++++++++++-------
>  2 files changed, 72 insertions(+), 23 deletions(-)
> 
> diff --git a/plugins/nbd/nbdkit-nbd-plugin.pod b/plugins/nbd/nbdkit-nbd-plugin.pod
> index 618058ac..151590d2 100644
> --- a/plugins/nbd/nbdkit-nbd-plugin.pod
> +++ b/plugins/nbd/nbdkit-nbd-plugin.pod
> @@ -4,9 +4,9 @@ nbdkit-nbd-plugin - nbdkit nbd plugin
> 
>  =head1 SYNOPSIS
> 
> - nbdkit nbd { socket=SOCKNAME | hostname=HOST [port=PORT] | [uri=]URI }
> -    [export=NAME] [retry=N] [shared=BOOL] [tls=MODE] [tls-certificates=DIR]
> -    [tls-verify=BOOL] [tls-username=NAME] [tls-psk=FILE]
> + nbdkit nbd { socket=SOCKNAME | { hostname=HOST | vsock_cid=CID } [port=PORT] |
> +      [uri=]URI } [export=NAME] [retry=N] [shared=BOOL] [tls=MODE]
> +    [tls-certificates=DIR] [tls-verify=BOOL] [tls-username=NAME] [tls-psk=FILE]
> 
>  =head1 DESCRIPTION
> 
> @@ -27,8 +27,8 @@ TCP and use plaintext only on a Unix socket.
> 
>  =head1 PARAMETERS
> 
> -One of B<socket>, B<hostname> or B<uri> must be provided to designate
> -the server. The server can speak either new or old style
> +One of B<socket>, B<hostname>, B<vsock_cid> or B<uri> must be provided
> +to designate the server. The server can speak either new or old style
>  protocol. C<uri=> is a magic config key and may be omitted in most
>  cases.  See L<nbdkit(1)/Magic parameters>.
> 
> @@ -47,8 +47,10 @@ Connect to the NBD server at the given remote C<HOST> using a TCP socket.
> 
>  =item B<port=>PORT
> 
> -When B<hostname> is supplied, use B<PORT> instead of the default port
> -10809.
> +When B<hostname> or B<vsock_cid> is supplied, use B<PORT> instead of
> +the default port 10809.  For TCP, the port may be a 16-bit number or a
> +non-numeric string used to look up the well-known port for a service
> +name; for VSOCK, the port must be a 32-bit number.
> 
>  =item B<export=>NAME
> 
> @@ -84,13 +86,23 @@ against libnbd:
> 
>  When B<uri> is supplied, decode B<URI> to determine the address to
>  connect to. A URI can specify a TCP connection (such as
> -C<nbd://localhost:10809/export>) or a Unix socket (such as
> -C<nbd+unix:///export?socket=/path/to/sock>).  Remember to use proper
> +C<nbd://localhost:10809/export>), a Unix socket (such as
> +C<nbd+unix:///export?socket=/path/to/sock>), or a vsock connection
> +(such as C<nbd+vsock:///2:10809/export>).  Remember to use proper
>  shell quoting to prevent B<URI> from accidentally being handled as a
>  shell glob. The B<uri> parameter is only available when the plugin was
>  compiled against libnbd with URI support; C<nbdkit --dump-plugin nbd>
>  will contain C<libnbd_uri=1> if this is the case.
> 
> +=item B<vsock_cid=>CID
> +
> +Connect to the NBD server at the given vsock cid (for example, in a
> +guest VM, using the cid 2 will connect to a server in the host).  This
> +only works for platforms with the C<AF_VSOCK> family of sockets and
> +libnbd new enough to use it; C<nbdkit --dump-plugin nbd> will contain
> +C<libnbd_vsock=1> if this is the case.  For more details on AF_VSOCK,
> +see L<nbdkit-service(1)/AF_VSOCK>.
> +
>  =item B<tls=>MODE
> 
>  Selects which TLS mode to use with the server. If no other tls option
> diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
> index d020beec..0bb5ff9f 100644
> --- a/plugins/nbd/nbd.c
> +++ b/plugins/nbd/nbd.c
> @@ -46,6 +46,7 @@
>  #include <semaphore.h>
>  #include <poll.h>
>  #include <fcntl.h>
> +#include <sys/socket.h>
> 
>  #include <libnbd.h>
> 
> @@ -56,6 +57,12 @@
>  #include "cleanup.h"
>  #include "utils.h"
> 
> +#if !defined AF_VSOCK || !LIBNBD_HAVE_NBD_CONNECT_VSOCK
> +#define USE_VSOCK 0
> +#else
> +#define USE_VSOCK 1
> +#endif
> +
>  /* The per-transaction details */
>  struct transaction {
>    int64_t cookie;
> @@ -80,8 +87,15 @@ static char *sockname;
> 
>  /* Connect to server via TCP socket */
>  static const char *hostname;
> +
> +/* Valid with TCP or VSOCK */
>  static const char *port;
> 
> +/* Connect to server via AF_VSOCK socket */
> +static const char *raw_cid;
> +static uint32_t cid;
> +static uint32_t vport;
> +
>  /* Connect to server via URI */
>  static const char *uri;
> 
> @@ -116,10 +130,10 @@ nbdplug_unload (void)
>  }
> 
>  /* Called for each key=value passed on the command line.  This plugin
> - * accepts socket=<sockname>, hostname=<hostname>/port=<port>, or
> - * [uri=]<uri> (exactly one connection required), and optional
> - * parameters export=<name>, retry=<n>, shared=<bool> and various
> - * tls settings.
> + * accepts socket=<sockname>, hostname=<hostname>/port=<port>,
> + * vsock_cid=<cid>/port=<port>, or [uri=]<uri> (exactly one connection
> + * required), and optional parameters export=<name>, retry=<n>,
> + * shared=<bool> and various tls settings.
>   */
>  static int
>  nbdplug_config (const char *key, const char *value)
> @@ -137,6 +151,10 @@ nbdplug_config (const char *key, const char *value)
>      hostname = value;
>    else if (strcmp (key, "port") == 0)
>      port = value;
> +  else if (strcmp (key, "vsock_cid") == 0 ||
> +           strcmp (key, "vsock-cid") == 0 ||
> +           strcmp (key, "cid") == 0)
> +    raw_cid = value;
>    else if (strcmp (key, "uri") == 0)
>      uri = value;
>    else if (strcmp (key, "export") == 0)
> @@ -198,12 +216,8 @@ nbdplug_config_complete (void)
>    if (sockname) {
>      struct sockaddr_un sock;
> 
> -    if (hostname || port) {
> -      nbdkit_error ("cannot mix Unix socket and TCP hostname/port parameters");
> -      return -1;
> -    }
> -    else if (uri) {
> -      nbdkit_error ("cannot mix Unix socket and URI parameters");
> +    if (hostname || port || raw_cid || uri) {
> +      nbdkit_error ("cannot mix Unix socket with other transport parameters");
>        return -1;
>      }
>      if (strlen (sockname) > sizeof sock.sun_path) {
> @@ -212,13 +226,27 @@ nbdplug_config_complete (void)
>      }
>    }
>    else if (hostname) {
> -    if (uri) {
> -      nbdkit_error ("cannot mix TCP hostname/port and URI parameters");
> +    if (uri || raw_cid) {
> +      nbdkit_error ("cannot mix TCP hostname with other transport parameters");
>        return -1;
>      }
>      if (!port)
>        port = "10809";
>    }
> +  else if (raw_cid) {
> +#if !USE_VSOCK
> +    nbdkit_error ("libnbd was compiled without vsock support");
> +    return -1;
> +#else
> +    if (uri) {
> +      nbdkit_error ("cannot mix VSOCK with other transport parameters");
> +      return -1;
> +    }
> +    if (nbdkit_parse_uint32_t ("vsock_cid", raw_cid, &cid) == -1 ||
> +        nbdkit_parse_uint32_t ("port", port, &vport) == -1)
> +      return -1;
> +#endif
> +  }
>    else if (uri) {
>      struct nbd_handle *nbd = nbd_create ();
> 
> @@ -237,7 +265,8 @@ nbdplug_config_complete (void)
>      }
>      nbd_close (nbd);
>    } else {
> -    nbdkit_error ("must supply socket=, hostname= or uri= of external NBD server");
> +    nbdkit_error ("must supply socket=, hostname=, vsock_cid= or uri= of "
> +                  "external NBD server");
>      return -1;
>    }
> 
> @@ -271,7 +300,8 @@ nbdplug_config_complete (void)
>    "[uri=]<URI>            URI of an NBD socket to connect to (if supported).\n" \
>    "socket=<SOCKNAME>      The Unix socket to connect to.\n" \
>    "hostname=<HOST>        The hostname for the TCP socket to connect to.\n" \
> -  "port=<PORT>            TCP port or service name to use (default 10809).\n" \
> +  "vhost_cid=<CID>        The cid for the VSOCK socket to connect to.\n" \
> +  "port=<PORT>            TCP/VHOST port or service name to use (default 10809).\n" \
>    "export=<NAME>          Export name to connect to (default \"\").\n" \
>    "retry=<N>              Retry connection up to N seconds (default 0).\n" \
>    "shared=<BOOL>          True to share one server connection among all clients,\n" \
> @@ -294,6 +324,7 @@ nbdplug_dump_plugin (void)
>    printf ("libnbd_version=%s\n", nbd_get_version (nbd));
>    printf ("libnbd_tls=%d\n", nbd_supports_tls (nbd));
>    printf ("libnbd_uri=%d\n", nbd_supports_uri (nbd));
> +  printf ("libnbd_vsock=%d\n", USE_VSOCK);
>    nbd_close (nbd);
>  }
> 
> @@ -484,6 +515,12 @@ nbdplug_open_handle (int readonly)
>      r = nbd_connect_uri (h->nbd, uri);
>    else if (sockname)
>      r = nbd_connect_unix (h->nbd, sockname);
> +  else if (raw_cid)
> +#if !USE_VSOCK
> +    abort ();
> +#else
> +    r = nbd_connect_vsock (h->nbd, cid, vport);
> +#endif
>    else
>      r = nbd_connect_tcp (h->nbd, hostname, port);
>    if (r == -1) {
> -- 
> 2.21.0
> 
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW




More information about the Libguestfs mailing list