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 <mwilck@xxxxxxxx> --- Makefile.inc | 4 +++- multipathd/main.c | 18 ++++++++++++------ multipathd/multipathd.socket.in | 3 ++- multipathd/uxlsnr.c | 33 ++++++++++++++++++++++----------- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/Makefile.inc b/Makefile.inc index 4015006..d0fecc3 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -80,6 +80,7 @@ kernel_incdir := /usr/include sysdir_bin := $(sys_execprefix)bin abstract_socket := @/org/kernel/linux/storage/multipathd +pathname_socket := /run/multipathd.socket ifeq ($(V),) Q := @ @@ -172,5 +173,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) -e 's:@SYSDIR_BIN@:'$(sysdir_bin)': g' \ -e 's:@RUNTIME_DIR@:'$(runtimedir)':g' \ -e 's/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g' \ - -e 's,@MPATH_SOCKET@,'$(abstract_socket)',g' \ + -e 's,@ABSTRACT_SOCKET@,'$(abstract_socket)',g' \ + -e 's,@PATHNAME_SOCKET@,'$(pathname_socket)',g' \ $< >$@ diff --git a/multipathd/main.c b/multipathd/main.c index 602215c..ac204b2 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1869,9 +1869,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]); @@ -1889,16 +1893,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; @@ -1924,7 +1930,7 @@ uxlsnrloop (void * ap) == DAEMON_CONFIGURE) handle_signals(false); - 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.in b/multipathd/multipathd.socket.in index c0e86c3..11002fc 100644 --- a/multipathd/multipathd.socket.in +++ b/multipathd/multipathd.socket.in @@ -7,7 +7,8 @@ ConditionVirtualization=!container Before=sockets.target [Socket] -ListenStream=@MPATH_SOCKET@ +ListenStream=@ABSTRACT_SOCKET@ +ListenStream=@PATHNAME_SOCKET@ [Install] # Socket activation for multipathd is disabled by default. diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c index 79e28e4..aa6aae7 100644 --- a/multipathd/uxlsnr.c +++ b/multipathd/uxlsnr.c @@ -69,7 +69,8 @@ struct client { /* Indices for array of poll fds */ enum { - POLLFD_UX = 0, + POLLFD_UX1 = 0, + POLLFD_UX2, POLLFD_NOTIFY, POLLFD_IDLE, POLLFDS_BASE, @@ -164,9 +165,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); list_for_each_entry_safe(client_loop, client_tmp, &clients, node) { @@ -614,20 +616,24 @@ static void handle_client(struct client *c, struct vectors *vecs, short revents) /* * 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) { 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, .mp_wd = -1, }; struct vectors *vecs = trigger_data; - 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 = calloc(1, max_pfds * sizeof(*polls)); if (!polls) { @@ -678,8 +684,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 @@ -687,7 +695,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); @@ -771,9 +779,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) -- 2.48.1