Nir Soffer
2021-Nov-07 13:27 UTC
[Libguestfs] [PATCH libnbd 0/2] Support concurrent connections using socket activation
Add missing test for socket activation and fix the server socket to use larger backlog, allowing concurrent connections. Nir Soffer (2): tests: Test nbd_connect_systemd_socket_activation socket-activation: Allow multiple connections generator/states-connect-socket-activation.c | 2 +- tests/Makefile.am | 5 ++ tests/connect-systemd-socket-activation.c | 83 ++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tests/connect-systemd-socket-activation.c -- 2.31.1
Nir Soffer
2021-Nov-07 13:27 UTC
[Libguestfs] [PATCH libnbd 1/2] tests: Test nbd_connect_systemd_socket_activation
Test connecting using systemd socket activation, and using the handle URI to connect additional handles. The tests reveals a deadlock when closing the first handle owning the nbdkit server. Closing the first handle last avoids this issue. Signed-off-by: Nir Soffer <nsoffer at redhat.com> --- tests/Makefile.am | 5 ++ tests/connect-systemd-socket-activation.c | 83 +++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tests/connect-systemd-socket-activation.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 7f00f6f..1451fb8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -192,6 +192,7 @@ check_PROGRAMS += \ opt-list \ opt-info \ opt-list-meta \ + connect-systemd-socket-activation \ connect-unix \ connect-tcp \ connect-tcp6 \ @@ -235,6 +236,7 @@ TESTS += \ opt-list \ opt-info \ opt-list-meta \ + connect-systemd-socket-activation \ connect-unix \ connect-tcp \ connect-tcp6 \ @@ -424,6 +426,9 @@ opt_info_LDADD = $(top_builddir)/lib/libnbd.la opt_list_meta_SOURCES = opt-list-meta.c opt_list_meta_LDADD = $(top_builddir)/lib/libnbd.la +connect_systemd_socket_activation_SOURCES = connect-systemd-socket-activation.c +connect_systemd_socket_activation_LDADD = $(top_builddir)/lib/libnbd.la + connect_unix_SOURCES = connect-unix.c connect_unix_LDADD = $(top_builddir)/lib/libnbd.la diff --git a/tests/connect-systemd-socket-activation.c b/tests/connect-systemd-socket-activation.c new file mode 100644 index 0000000..d64319a --- /dev/null +++ b/tests/connect-systemd-socket-activation.c @@ -0,0 +1,83 @@ +/* NBD client library in userspace + * Copyright (C) 2021 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Test connecting using systemd socket activation. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <libnbd.h> + +#define CONNECTIONS 4 + +int +main (int argc, char *argv[]) +{ + char *args[] = {"nbdkit", "-f", "memory", "size=1m", NULL}; + struct nbd_handle *nbd[CONNECTIONS] = {0}; + char *uri = NULL; + int result = EXIT_FAILURE; + + printf("Connecting handle 0 with systemd socket actication\n"); + + nbd[0] = nbd_create (); + if (nbd[0] == NULL) + goto out; + + if (nbd_connect_systemd_socket_activation (nbd[0], args) == -1) + goto out; + + uri = nbd_get_uri (nbd[0]); + if (uri == NULL) + goto out; + + printf("Using URI: %s\n", uri); + + for (int i = 1; i < CONNECTIONS; i++) { + printf ("Connecting handle %d to URI\n", i); + + nbd[i] = nbd_create (); + if (nbd[i] == NULL) + goto out; + + if (nbd_connect_uri (nbd[i], uri) == -1) + goto out; + } + + printf ("All handles connected\n"); + result = EXIT_SUCCESS; + +out: + if (result == EXIT_FAILURE) + fprintf (stderr, "%s\n", nbd_get_error ()); + + free (uri); + + /* Closing the first connection deadlocks, so we close the additional + * connections first. */ + for (int i = CONNECTIONS - 1; i >= 0; i--) { + if (nbd[i]) { + printf ("Closing handle %d\n", i); + nbd_close (nbd[i]); + } + } + + exit (result); +} -- 2.31.1
Nir Soffer
2021-Nov-07 13:27 UTC
[Libguestfs] [PATCH libnbd 2/2] socket-activation: Allow multiple connections
When using qemu-nbd with systemd socket activation, trying to connect additional clients concurrently fails with: nbd_connect_uri: connect: server backlog overflowed, see https://bugzilla.redhat.com/1925045: Resource temporarily unavailable But this bug was fixed in qemu-nbd long time ago; turns out that libnbd has the same bug, creating the server socket with: listen(s, 1); Use SOMAXCONN so we can have multiple connections for better performance. I think this can be very useful for nbdcopy. Signed-off-by: Nir Soffer <nsoffer at redhat.com> --- generator/states-connect-socket-activation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/states-connect-socket-activation.c b/generator/states-connect-socket-activation.c index 800d963..2abf61b 100644 --- a/generator/states-connect-socket-activation.c +++ b/generator/states-connect-socket-activation.c @@ -147,7 +147,7 @@ STATE_MACHINE { return 0; } - if (listen (s, 1) == -1) { + if (listen (s, SOMAXCONN) == -1) { SET_NEXT_STATE (%.DEAD); set_error (errno, "listen"); close (s); -- 2.31.1