Eric Blake
2019-Nov-22 20:13 UTC
[Libguestfs] [nbdkit PATCH] nbd: Add vsock_cid= transport option
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@redhat.com> --- 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
Richard W.M. Jones
2019-Nov-22 20:43 UTC
Re: [Libguestfs] [nbdkit PATCH] nbd: Add vsock_cid= transport option
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@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@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
Maybe Matching Threads
- [nbdkit PATCH] nbd: Add vsock-cid= transport option
- Re: [nbdkit PATCH] nbd: Add vsock-cid= transport option
- [nbdkit PATCH 0/3] .list_exports in nbd plugin
- [PATCH nbdkit 0/9] nbd: Implement command= and socket-fd= parameters.
- [PATCH nbdkit 0/5 NOT WORKING] nbd: Implement command= and socket-fd= parameters.