[Libguestfs] [PATCH nbdkit] Add support for AF_VSOCK.
Eric Blake
eblake at redhat.com
Fri Oct 18 16:16:16 UTC 2019
On 10/18/19 10:38 AM, Richard W.M. Jones wrote:
> On platforms which support it (only Linux currently) nbdkit can act as
> a vsock server. Guests running on the host see a raw NBD socket which
> it can connect to by opening an AF_VSOCK connection. (Although only
> libnbd supports this).
>
> The current limitations are:
>
> * nbdkit can only act as a host (cid == VMADDR_CID_HOST == 2).
How hard would it be to allow a different cid to run a server on the
guest and client on the host?
>
> * There is no access control. Any guest which has vsock enabled can
> open the socket.
Well, there's TLS if you need it.
>
> * nbdkit can only listen on either TCP/IP or AF_VSOCK, not both at
> the same time. (The same currently applies to TCP/IP vs AF_UNIX so
> this is not a new restriction).
>
> * Lacks a test because you cannot use vsock to communicate host to
> host.
Yeah, this is one case where testing requires a guest.
> +If you see the error C<unable to open vhost-vsock device> then you may
> +have to unload the VMCI transport:
> +
> + modprobe -r vmw_vsock_vmci_transport
Is that in the host or in the guest?
> @@ -826,15 +842,22 @@ start_serving (void)
> size_t nr_socks;
> size_t i;
>
> - /* If the user has mixed up -p/-U/-s options, then give an error.
> + /* If the user has mixed up -p/--run/-s/-U/--vsock options, then
> + * give an error.
> *
> * XXX Actually the server could easily be extended to handle both
> * TCP/IP and Unix sockets, or even multiple TCP/IP ports.
> */
> - if ((port && unixsocket) || (port && listen_stdin) ||
> - (unixsocket && listen_stdin) || (listen_stdin && run)) {
> + if ((port && unixsocket) ||
> + (port && listen_stdin) ||
> + (unixsocket && listen_stdin) ||
> + (listen_stdin && run) ||
> + (vsock && unixsocket) ||
> + (vsock && listen_stdin) ||
> + (vsock && run)) {
Lots of pairings. I was trying to figure out if:
if (!!port + !!unixsocket + listen_stdin + run + vsock > 1)
is any easier to write, but not quite, since we DO allow port and vsock.
So keeping the list of pairs seems to be the best we can do.
> @@ -247,6 +252,74 @@ bind_tcpip_socket (size_t *nr_socks)
> return socks;
> }
>
> +int *
> +bind_vsock (size_t *nr_socks)
> +{
> +#ifdef AF_VSOCK
> + uint32_t vsock_port;
> + int sock;
> + int *ret;
> + struct sockaddr_vm addr;
> +
> + if (port == NULL)
> + vsock_port = 10809;
> + else {
> + /* --port parameter must be numeric for vsock, unless
> + * /etc/services is extended but that seems unlikely. XXX
> + */
> + if (nbdkit_parse_uint32_t ("port", port, &vsock_port) == -1)
> + exit (EXIT_FAILURE);
> + }
> +
> +#ifdef SOCK_CLOEXEC
> + sock = socket (AF_VSOCK, SOCK_STREAM|SOCK_CLOEXEC, 0);
> +#else
> + /* Fortunately, this code is only run at startup, so there is no
> + * risk of the fd leaking to a plugin's fork()
> + */
> + sock = set_cloexec (socket (AF_VSOCK, SOCK_STREAM, 0));
Even better, all known platforms with AF_VSOCK have SOCK_CLOEXEC. Make
this #else just be an #error.
> +#endif
> + if (sock == -1) {
> + perror ("bind_unix_socket: socket");
> + exit (EXIT_FAILURE);
> + }
Also, it wouldn't be that much harder for a followup patch exposing:
nbdkit nbd vsock_cid=... vsock_port=...
to have our passthrough wrapper call into libnbd's nbd_connect_vsock,
and let nbdkit transparently convert from vsock server to TCP/Unix client.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
More information about the Libguestfs
mailing list