device-mapper-multipath/0023-multipathd-allow-receiving-two-socket-fds-from-syste.patch
Benjamin Marzinski 5b86fc9dcf device-mapper-multipath-0.9.9-7
Add 0018-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch
Add 0019-multipath-tools-add-helper-mpath_fill_sockaddr__.patch
Add 0020-libmpathutil-add-support-for-Unix-pathname-sockets.patch
Add 0021-libmpathutil-move-systemd_listen_fds-support-into-mu.patch
Add 0022-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch
Add 0023-multipathd-allow-receiving-two-socket-fds-from-syste.patch
Add 0024-multipathd-listen-on-pathname-and-abstract-socket-by.patch
Add 0025-libmpathcmd-try-both-abstract-and-pathname-sockets.patch
Add 0026-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch
Add 0027-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch
Add 0028-multipath-clean-up-find_multipaths-documentation.patch
Add 0029-multipathd-Add-multipathd-man-page-section-about-soc.patch
  * Fixes RHEL-82180 ("RFE: Enable multipathd to communicate with a
    process in another network namespace")
Resolves: RHEL-82180
2025-03-11 16:40:30 -04:00

195 lines
6.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
Makefile.inc | 3 ++-
multipathd/main.c | 18 ++++++++++++------
multipathd/multipathd.socket.in | 3 ++-
multipathd/uxlsnr.c | 33 ++++++++++++++++++++++-----------
4 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 1ef3f7f8..07c0ae80 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -76,6 +76,7 @@ libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr
kernel_incdir := /usr/include
abstract_socket := @/org/kernel/linux/storage/multipathd
+pathname_socket := /run/multipathd.socket
ifeq ($(V),)
Q := @
@@ -166,4 +167,4 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version)
%: %.in
@echo creating $@
- $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g;s,@MPATH_SOCKET@,'$(abstract_socket)',g' $< >$@
+ $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g;s,@ABSTRACT_SOCKET@,'$(abstract_socket)',g;s,@PATHNAME_SOCKET@,'$(pathname_socket)',g' $< >$@
diff --git a/multipathd/main.c b/multipathd/main.c
index 9f15d2f7..2fef0c64 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1865,9 +1865,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]);
@@ -1885,16 +1889,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;
@@ -1920,7 +1926,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 4ed9c1ff..5ed24757 100644
--- a/multipathd/multipathd.socket.in
+++ b/multipathd/multipathd.socket.in
@@ -8,7 +8,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 51b5e51d..bbf891ba 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)