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