[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