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
195 lines
6.5 KiB
Diff
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)
|