From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 12 Feb 2025 20:27:18 +0100 Subject: [PATCH] multipathd: allow receiving two socket fds from systemd Add another ListenStream directive in multipathd.socket for a Unix pathname socket. In multipathd, read both socket fds from systemd, and open both when they are defined. Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- Makefile.inc | 1 + multipathd/main.c | 18 ++++++++++++------ multipathd/multipathd.socket | 1 + multipathd/uxlsnr.c | 33 ++++++++++++++++++++++----------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Makefile.inc b/Makefile.inc index 308f0da0..1de6c8a0 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -83,6 +83,7 @@ pkgconfdir = $(usrlibdir)/pkgconfig runtimedir = /$(RUN) abstract_socket := @/org/kernel/linux/storage/multipathd +pathname_socket := /run/multipathd.socket GZIP = gzip -9 -c RM = rm -f diff --git a/multipathd/main.c b/multipathd/main.c index 6afb7154..01903914 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1721,9 +1721,13 @@ static int get_systemd_sockets(long *ux_sock) { int num = sd_listen_fds(0); - if (num > 1) { + if (num > 2) { condlog(3, "sd_listen_fds returned %d fds", num); return -1; + } else if (num == 2) { + ux_sock[0] = SD_LISTEN_FDS_START + 0; + ux_sock[1] = SD_LISTEN_FDS_START + 1; + condlog(3, "using fd %ld and %ld from sd_listen_fds", ux_sock[0], ux_sock[1]); } else if (num == 1) { ux_sock[0] = SD_LISTEN_FDS_START + 0; condlog(3, "using fd %ld from sd_listen_fds", ux_sock[0]); @@ -1741,16 +1745,18 @@ static int get_systemd_sockets(long *ux_sock __attribute__((unused))) static void * uxlsnrloop (void * ap) { - long ux_sock; + long ux_sock[2] = {-1, -1}; int num; pthread_cleanup_push(rcu_unregister, NULL); rcu_register_thread(); num = get_systemd_sockets(&ux_sock); - if (num < 1) - ux_sock = ux_socket_listen(DEFAULT_SOCKET); - if (ux_sock == -1) { + if (num < 1) { + ux_sock[0] = ux_socket_listen(DEFAULT_SOCKET); + num = 1; + } + if (ux_sock[0] == -1) { condlog(1, "could not create uxsock: %d", errno); exit_daemon(); goto out; @@ -1824,7 +1830,7 @@ uxlsnrloop (void * ap) set_handler_callback(UNSETMARGINAL|MAP, cli_unset_all_marginal); umask(077); - uxsock_listen(1, &ux_sock, ap); + uxsock_listen(num, ux_sock, ap); out_sock: pthread_cleanup_pop(1); /* uxsock_cleanup */ diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket index 3c20a2ff..629a0828 100644 --- a/multipathd/multipathd.socket +++ b/multipathd/multipathd.socket @@ -9,6 +9,7 @@ Before=sockets.target [Socket] ListenStream=@/org/kernel/linux/storage/multipathd +ListenStream=/run/multipathd.socket [Install] WantedBy=sockets.target diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c index 7599291a..9f8c7db1 100644 --- a/multipathd/uxlsnr.c +++ b/multipathd/uxlsnr.c @@ -48,7 +48,8 @@ struct client { /* Indices for array of poll fds */ enum { - POLLFD_UX = 0, + POLLFD_UX1 = 0, + POLLFD_UX2, POLLFD_NOTIFY, POLLFDS_BASE, }; @@ -168,9 +169,10 @@ void uxsock_cleanup(void *arg) { struct client *client_loop; struct client *client_tmp; - long ux_sock = (long)arg; + long *ux_sock = (long *)arg; - close(ux_sock); + close(ux_sock[0]); + close(ux_sock[1]); close(notify_fd); free(watch_config_dir); @@ -332,22 +334,26 @@ static int uxsock_trigger(char *str, char **reply, int *len, /* * entry point */ -void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data) +void *uxsock_listen(int n_socks, long *ux_sock_in, void *trigger_data) { int rlen; char *inbuf; char *reply; sigset_t mask; int max_pfds = MIN_POLLS + POLLFDS_BASE; + long ux_sock[2] = {-1, -1}; /* conf->sequence_nr will be 1 when uxsock_listen is first called */ unsigned int sequence_nr = 0; struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; - if (n_socks != 1) { - condlog(0, "uxsock: no socket fds"); + if (n_socks < 1 || n_socks > 2) { + condlog(0, "uxsock: unsupported number of socket fds"); exit_daemon(); return NULL; - } + } else if (n_socks == 2) + ux_sock[1] = ux_sock_in[1]; + ux_sock[0] = ux_sock_in[0]; + condlog(3, "uxsock: startup listener"); polls = MALLOC(max_pfds * sizeof(*polls)); if (!polls) { @@ -389,8 +395,10 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data) } } if (num_clients < MAX_CLIENTS) { - polls[POLLFD_UX].fd = ux_sock[0]; - polls[POLLFD_UX].events = POLLIN; + polls[POLLFD_UX1].fd = ux_sock[0]; + polls[POLLFD_UX1].events = POLLIN; + polls[POLLFD_UX2].fd = ux_sock[1]; + polls[POLLFD_UX2].events = POLLIN; } else { /* * New clients can't connect, num_clients won't grow @@ -398,7 +406,7 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data) */ condlog(1, "%s: max client connections reached, pausing polling", __func__); - polls[POLLFD_UX].fd = -1; + polls[POLLFD_UX1].fd = polls[POLLFD_UX2].fd = -1; } reset_watch(notify_fd, &wds, &sequence_nr); @@ -510,9 +518,12 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data) handle_signals(true); /* see if we got a new client */ - if (polls[POLLFD_UX].revents & POLLIN) { + if (polls[POLLFD_UX1].revents & POLLIN) { new_client(ux_sock[0]); } + if (polls[POLLFD_UX2].revents & POLLIN) { + new_client(ux_sock[1]); + } /* handle inotify events on config files */ if (polls[POLLFD_NOTIFY].revents & POLLIN)