import UBI device-mapper-multipath-0.8.7-35.el9_6.1

This commit is contained in:
eabdullin 2025-06-24 11:10:01 +00:00
parent a475029b8e
commit 3193bb46da
13 changed files with 1114 additions and 1 deletions

View File

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Tue, 11 Feb 2025 16:51:59 +0100
Subject: [PATCH] multipath-tools: move DEFAULT_SOCKET definition into
Makefile.inc
This enables configuring the socket name. Follow up patches will
add more flexibility for configuring the sockets.
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 | 4 +++-
libmpathcmd/mpath_cmd.h | 1 -
libmultipath/defaults.h | 1 -
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 4c452159..3746ceee 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -82,6 +82,8 @@ includedir = $(prefix)/usr/include
pkgconfdir = $(usrlibdir)/pkgconfig
runtimedir = /$(RUN)
+abstract_socket := /org/kernel/linux/storage/multipathd
+
GZIP = gzip -9 -c
RM = rm -f
LN = ln -sf
@@ -122,7 +124,7 @@ WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
-Wstrict-prototypes
CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
- -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" -DRUNTIME_DIR=\"$(runtimedir)\" \
+ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" -DRUNTIME_DIR=\"$(runtimedir)\" -DDEFAULT_SOCKET=\"$(abstract_socket)\" \
-MMD -MP
BIN_CFLAGS = -fPIE -DPIE
LIB_CFLAGS = -fPIC
diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h
index ccfd35f2..8707a42a 100644
--- a/libmpathcmd/mpath_cmd.h
+++ b/libmpathcmd/mpath_cmd.h
@@ -30,7 +30,6 @@
extern "C" {
#endif
-#define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
#define DEFAULT_REPLY_TIMEOUT 4000
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
index 5e77387e..1ab5b99c 100644
--- a/libmultipath/defaults.h
+++ b/libmultipath/defaults.h
@@ -64,7 +64,6 @@
#define DEV_LOSS_TMO_UNSET 0U
#define MAX_DEV_LOSS_TMO UINT_MAX
#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid"
-#define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
#define DEFAULT_CONFIGFILE "/etc/multipath.conf"
#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"

View File

@ -0,0 +1,157 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 14 Feb 2025 21:57:02 +0100
Subject: [PATCH] multipath-tools: add helper mpath_fill_sockaddr__()
Create a static new helper function which is used by both libmpathcmd
and libmpathutil and fills in the socket address name from the compile-time
default. The function is able to handle both abstract and pathname sockets,
but more changes are needed to make the latter actually work.
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 | 2 +-
libmpathcmd/mpath_cmd.c | 11 +++--------
libmpathcmd/mpath_fill_sockaddr.c | 30 ++++++++++++++++++++++++++++++
libmultipath/uxsock.c | 15 ++++++---------
4 files changed, 40 insertions(+), 18 deletions(-)
create mode 100644 libmpathcmd/mpath_fill_sockaddr.c
diff --git a/Makefile.inc b/Makefile.inc
index 3746ceee..308f0da0 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -82,7 +82,7 @@ includedir = $(prefix)/usr/include
pkgconfdir = $(usrlibdir)/pkgconfig
runtimedir = /$(RUN)
-abstract_socket := /org/kernel/linux/storage/multipathd
+abstract_socket := @/org/kernel/linux/storage/multipathd
GZIP = gzip -9 -c
RM = rm -f
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
index 60b2d965..146e790d 100644
--- a/libmpathcmd/mpath_cmd.c
+++ b/libmpathcmd/mpath_cmd.c
@@ -24,11 +24,13 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <poll.h>
+#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "mpath_cmd.h"
+#include "mpath_fill_sockaddr.c"
/*
* keep reading until its all read
@@ -101,14 +103,6 @@ int __mpath_connect(int nonblocking)
struct sockaddr_un addr;
int flags = 0;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- addr.sun_path[0] = '\0';
- strncpy(&addr.sun_path[1], DEFAULT_SOCKET, sizeof(addr.sun_path) - 1);
- len = strlen(DEFAULT_SOCKET) + 1 + sizeof(sa_family_t);
- if (len > sizeof(struct sockaddr_un))
- len = sizeof(struct sockaddr_un);
-
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd == -1)
return -1;
@@ -119,6 +113,7 @@ int __mpath_connect(int nonblocking)
(void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
}
+ len = mpath_fill_sockaddr__(&addr, DEFAULT_SOCKET);
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
int err = errno;
diff --git a/libmpathcmd/mpath_fill_sockaddr.c b/libmpathcmd/mpath_fill_sockaddr.c
new file mode 100644
index 00000000..86c118d4
--- /dev/null
+++ b/libmpathcmd/mpath_fill_sockaddr.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ * SPDX-license-identifier: LGPL-2.1-or-newer
+ */
+
+static size_t mpath_fill_sockaddr__(struct sockaddr_un *addr, const char *name)
+{
+ size_t len;
+
+ addr->sun_family = AF_LOCAL;
+
+ if (name[0] != '@') {
+ /* Pathname socket. This should be NULL-terminated. */
+ strncpy(&addr->sun_path[0], name, sizeof(addr->sun_path) - 1);
+ addr->sun_path[sizeof(addr->sun_path) - 1] = '\0';
+ len = offsetof(struct sockaddr_un, sun_path) + strlen(name) + 1;
+ } else {
+ addr->sun_path[0] = '\0';
+ /*
+ * The abstract socket's name doesn't need to be NULL terminated.
+ * Actually, a trailing NULL would be considered part of the socket name.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ strncpy(&addr->sun_path[1], &name[1], sizeof(addr->sun_path) - 1);
+#pragma GCC diagnostic pop
+ len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
+ }
+ return len > sizeof(*addr) ? sizeof(*addr) : len;
+}
diff --git a/libmultipath/uxsock.c b/libmultipath/uxsock.c
index 6adeedfc..de1a21a3 100644
--- a/libmultipath/uxsock.c
+++ b/libmultipath/uxsock.c
@@ -6,12 +6,15 @@
*/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <stdarg.h>
+#include <stddef.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include <poll.h>
#include <signal.h>
@@ -34,6 +37,8 @@
static int _recv_packet(int fd, char **buf, unsigned int timeout,
ssize_t limit);
+#include "../libmpathcmd/mpath_fill_sockaddr.c"
+
/*
* create a unix domain socket and start listening on it
* return a file descriptor open on the socket
@@ -64,15 +69,7 @@ int ux_socket_listen(const char *name)
return -1;
}
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- addr.sun_path[0] = '\0';
- len = strlen(name) + 1;
- if (len >= sizeof(addr.sun_path))
- len = sizeof(addr.sun_path) - 1;
- memcpy(&addr.sun_path[1], name, len);
-
- len += sizeof(sa_family_t);
+ len = mpath_fill_sockaddr__(&addr, name);
if (bind(fd, (struct sockaddr *)&addr, len) == -1) {
condlog(3, "Couldn't bind to ux_socket, error %d", errno);
close(fd);

View File

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 14 Feb 2025 22:00:24 +0100
Subject: [PATCH] libmpathutil: add support for Unix pathname sockets
Pathname sockets need to be world read/writable in order to allow regular
users to read information from multipathd. Our SO_PEERCRED permission check
will make sure that they can't make configuration changes. Also, SO_REUSEADDR
doesn't work for pathname sockets as it does for abstract Unix sockets. A
possibly pre-existing socket file must be removed before trying to recreate it.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/uxsock.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/libmultipath/uxsock.c b/libmultipath/uxsock.c
index de1a21a3..b0ba7e3b 100644
--- a/libmultipath/uxsock.c
+++ b/libmultipath/uxsock.c
@@ -63,6 +63,11 @@ int ux_socket_listen(const char *name)
return fd;
}
#endif
+
+ /* This is after the PID check, so unlinking should be fine */
+ if (name[0] != '@' && unlink(name) == -1 && errno != ENOENT)
+ condlog(1, "Failed to unlink %s", name);
+
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd == -1) {
condlog(3, "Couldn't create ux_socket, error %d", errno);
@@ -76,6 +81,14 @@ int ux_socket_listen(const char *name)
return -1;
}
+ /*
+ * Socket needs to have rw permissions for everone.
+ * SO_PEERCRED makes sure that only root can modify things.
+ */
+ if (name[0] != '@' &&
+ chmod(name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == -1)
+ condlog(3, "failed to set permissions on %s: %s", name, strerror(errno));
+
if (listen(fd, 10) == -1) {
condlog(3, "Couldn't listen to ux_socket, error %d", errno);
close(fd);

View File

@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 12 Feb 2025 19:12:35 +0100
Subject: [PATCH] libmpathutil: move systemd_listen_fds() support into
multipathd
This feature is only used by multipathd.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/uxsock.c | 15 ---------------
multipathd/main.c | 28 +++++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/libmultipath/uxsock.c b/libmultipath/uxsock.c
index b0ba7e3b..2931405f 100644
--- a/libmultipath/uxsock.c
+++ b/libmultipath/uxsock.c
@@ -47,23 +47,8 @@ int ux_socket_listen(const char *name)
{
int fd;
size_t len;
-#ifdef USE_SYSTEMD
- int num;
-#endif
struct sockaddr_un addr;
-#ifdef USE_SYSTEMD
- num = sd_listen_fds(0);
- if (num > 1) {
- condlog(3, "sd_listen_fds returned %d fds", num);
- return -1;
- } else if (num == 1) {
- fd = SD_LISTEN_FDS_START + 0;
- condlog(3, "using fd %d from sd_listen_fds", fd);
- return fd;
- }
-#endif
-
/* This is after the PID check, so unlinking should be fine */
if (name[0] != '@' && unlink(name) == -1 && errno != ENOENT)
condlog(1, "Failed to unlink %s", name);
diff --git a/multipathd/main.c b/multipathd/main.c
index 8ec58f5d..30c4938f 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1757,15 +1757,41 @@ uevqloop (void * ap)
pthread_cleanup_pop(1);
return NULL;
}
+
+#ifdef USE_SYSTEMD
+static int get_systemd_sockets(long *ux_sock)
+{
+ int num = sd_listen_fds(0);
+
+ if (num > 1) {
+ condlog(3, "sd_listen_fds returned %d fds", num);
+ return -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]);
+ }
+ return num;
+}
+#else
+static int get_systemd_sockets(long *ux_sock __attribute__((unused)))
+{
+ return 0;
+}
+#endif
+
+
static void *
uxlsnrloop (void * ap)
{
long ux_sock;
+ int num;
pthread_cleanup_push(rcu_unregister, NULL);
rcu_register_thread();
- ux_sock = ux_socket_listen(DEFAULT_SOCKET);
+ num = get_systemd_sockets(&ux_sock);
+ if (num < 1)
+ ux_sock = ux_socket_listen(DEFAULT_SOCKET);
if (ux_sock == -1) {
condlog(1, "could not create uxsock: %d", errno);
exit_daemon();

View File

@ -0,0 +1,156 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 8 Sep 2021 08:29:20 +0200
Subject: [PATCH] multipathd: move uxsock_trigger() to uxlsnr.c
uxsock_trigger() really belongs into cli.c. I suppose that way back in
the past there were strong reasons to call this function via a
pointer. I don't think these reasons are valid any more. Moving
the function to cli.c allows restructuring the code.
No functional changes.
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/main.c | 44 +-------------------------------------------
multipathd/uxlsnr.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
multipathd/uxlsnr.h | 4 +---
3 files changed, 44 insertions(+), 48 deletions(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index 30c4938f..21f16b8f 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1615,48 +1615,6 @@ map_discovery (struct vectors * vecs)
return 0;
}
-int
-uxsock_trigger (char * str, char ** reply, int * len, bool is_root,
- void * trigger_data)
-{
- struct vectors * vecs;
- int r;
-
- *reply = NULL;
- *len = 0;
- vecs = (struct vectors *)trigger_data;
-
- if ((str != NULL) && (is_root == false) &&
- (strncmp(str, "list", strlen("list")) != 0) &&
- (strncmp(str, "show", strlen("show")) != 0)) {
- *reply = STRDUP("permission deny: need to be root");
- if (*reply)
- *len = strlen(*reply) + 1;
- return 1;
- }
-
- r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000);
-
- if (r > 0) {
- if (r == ETIMEDOUT)
- *reply = STRDUP("timeout\n");
- else
- *reply = STRDUP("fail\n");
- if (*reply)
- *len = strlen(*reply) + 1;
- r = 1;
- }
- else if (!r && *len == 0) {
- *reply = STRDUP("ok\n");
- if (*reply)
- *len = strlen(*reply) + 1;
- r = 0;
- }
- /* else if (r < 0) leave *reply alone */
-
- return r;
-}
-
int
uev_trigger (struct uevent * uev, void * trigger_data)
{
@@ -1866,7 +1824,7 @@ uxlsnrloop (void * ap)
set_handler_callback(UNSETMARGINAL|MAP, cli_unset_all_marginal);
umask(077);
- uxsock_listen(&uxsock_trigger, ux_sock, ap);
+ uxsock_listen(ux_sock, ap);
out_sock:
pthread_cleanup_pop(1); /* uxsock_cleanup */
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index dbee0d6f..a320a0c6 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -283,11 +283,51 @@ static void handle_inotify(int fd, struct watch_descriptors *wds)
condlog(1, "Multipath configuration updated.\nReload multipathd for changes to take effect");
}
+static int uxsock_trigger(char *str, char **reply, int *len,
+ bool is_root, void *trigger_data)
+{
+ struct vectors * vecs;
+ int r;
+
+ *reply = NULL;
+ *len = 0;
+ vecs = (struct vectors *)trigger_data;
+
+ if ((str != NULL) && (is_root == false) &&
+ (strncmp(str, "list", strlen("list")) != 0) &&
+ (strncmp(str, "show", strlen("show")) != 0)) {
+ *reply = strdup("permission deny: need to be root");
+ if (*reply)
+ *len = strlen(*reply) + 1;
+ return 1;
+ }
+
+ r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000);
+
+ if (r > 0) {
+ if (r == ETIMEDOUT)
+ *reply = strdup("timeout\n");
+ else
+ *reply = strdup("fail\n");
+ if (*reply)
+ *len = strlen(*reply) + 1;
+ r = 1;
+ }
+ else if (!r && *len == 0) {
+ *reply = strdup("ok\n");
+ if (*reply)
+ *len = strlen(*reply) + 1;
+ r = 0;
+ }
+ /* else if (r < 0) leave *reply alone */
+
+ return r;
+}
+
/*
* entry point
*/
-void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
- void * trigger_data)
+void *uxsock_listen(long ux_sock, void *trigger_data)
{
int rlen;
char *inbuf;
diff --git a/multipathd/uxlsnr.h b/multipathd/uxlsnr.h
index 18f008d7..60c3a2c7 100644
--- a/multipathd/uxlsnr.h
+++ b/multipathd/uxlsnr.h
@@ -3,10 +3,8 @@
#include <stdbool.h>
-typedef int (uxsock_trigger_fn)(char *, char **, int *, bool, void *);
-
void uxsock_cleanup(void *arg);
-void *uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
+void *uxsock_listen(long ux_sock,
void * trigger_data);
#endif

View File

@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Tue, 7 Sep 2021 22:08:53 +0200
Subject: [PATCH] multipathd: uxlsnr: use symbolic values for pollfd indices
Avoid hardcoding the indices as 0, 1, 2...
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/uxlsnr.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index a320a0c6..7c081799 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -46,8 +46,13 @@ struct client {
int fd;
};
-/* The number of fds we poll on, other than individual client connections */
-#define POLLFDS_BASE 2
+/* Indices for array of poll fds */
+enum {
+ POLLFD_UX = 0,
+ POLLFD_NOTIFY,
+ POLLFDS_BASE,
+};
+
#define POLLFD_CHUNK (4096 / sizeof(struct pollfd))
/* Minimum mumber of pollfds to reserve for clients */
#define MIN_POLLS (POLLFD_CHUNK - POLLFDS_BASE)
@@ -379,8 +384,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
}
}
if (num_clients < MAX_CLIENTS) {
- polls[0].fd = ux_sock;
- polls[0].events = POLLIN;
+ polls[POLLFD_UX].fd = ux_sock;
+ polls[POLLFD_UX].events = POLLIN;
} else {
/*
* New clients can't connect, num_clients won't grow
@@ -388,15 +393,15 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
*/
condlog(1, "%s: max client connections reached, pausing polling",
__func__);
- polls[0].fd = -1;
+ polls[POLLFD_UX].fd = -1;
}
reset_watch(notify_fd, &wds, &sequence_nr);
if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1))
- polls[1].fd = -1;
+ polls[POLLFD_NOTIFY].fd = -1;
else
- polls[1].fd = notify_fd;
- polls[1].events = POLLIN;
+ polls[POLLFD_NOTIFY].fd = notify_fd;
+ polls[POLLFD_NOTIFY].events = POLLIN;
/* setup the clients */
i = POLLFDS_BASE;
@@ -500,12 +505,12 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
handle_signals(true);
/* see if we got a new client */
- if (polls[0].revents & POLLIN) {
+ if (polls[POLLFD_UX].revents & POLLIN) {
new_client(ux_sock);
}
/* handle inotify events on config files */
- if (polls[1].revents & POLLIN)
+ if (polls[POLLFD_NOTIFY].revents & POLLIN)
handle_inotify(notify_fd, &wds);
}

View File

@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 12 Feb 2025 20:08:28 +0100
Subject: [PATCH] multipathd: make uxsock_listen() take a pointer to fd
This prepares being able to pass multiple socket fds.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/main.c | 2 +-
multipathd/uxlsnr.c | 11 ++++++++---
multipathd/uxlsnr.h | 3 +--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index 21f16b8f..6afb7154 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1824,7 +1824,7 @@ uxlsnrloop (void * ap)
set_handler_callback(UNSETMARGINAL|MAP, cli_unset_all_marginal);
umask(077);
- uxsock_listen(ux_sock, ap);
+ uxsock_listen(1, &ux_sock, ap);
out_sock:
pthread_cleanup_pop(1); /* uxsock_cleanup */
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index 7c081799..7599291a 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -332,7 +332,7 @@ static int uxsock_trigger(char *str, char **reply, int *len,
/*
* entry point
*/
-void *uxsock_listen(long ux_sock, void *trigger_data)
+void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data)
{
int rlen;
char *inbuf;
@@ -343,6 +343,11 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
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");
+ exit_daemon();
+ return NULL;
+ }
condlog(3, "uxsock: startup listener");
polls = MALLOC(max_pfds * sizeof(*polls));
if (!polls) {
@@ -384,7 +389,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
}
}
if (num_clients < MAX_CLIENTS) {
- polls[POLLFD_UX].fd = ux_sock;
+ polls[POLLFD_UX].fd = ux_sock[0];
polls[POLLFD_UX].events = POLLIN;
} else {
/*
@@ -506,7 +511,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
/* see if we got a new client */
if (polls[POLLFD_UX].revents & POLLIN) {
- new_client(ux_sock);
+ new_client(ux_sock[0]);
}
/* handle inotify events on config files */
diff --git a/multipathd/uxlsnr.h b/multipathd/uxlsnr.h
index 60c3a2c7..dc3857c4 100644
--- a/multipathd/uxlsnr.h
+++ b/multipathd/uxlsnr.h
@@ -4,7 +4,6 @@
#include <stdbool.h>
void uxsock_cleanup(void *arg);
-void *uxsock_listen(long ux_sock,
- void * trigger_data);
+void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data);
#endif

View File

@ -0,0 +1,188 @@
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 | 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)

View File

@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 12 Feb 2025 20:35:36 +0100
Subject: [PATCH] multipathd: listen on pathname and abstract socket by default
Pass both ABSTRACT_SOCKET and PATHNAME_SOCKET to the compiler at
build time, and listen on both sockets by default.
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 | 2 +-
libmpathcmd/mpath_cmd.c | 2 +-
multipathd/main.c | 11 ++++++-----
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 1de6c8a0..0a25c7b1 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -125,7 +125,7 @@ WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
-Wstrict-prototypes
CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
- -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" -DRUNTIME_DIR=\"$(runtimedir)\" -DDEFAULT_SOCKET=\"$(abstract_socket)\" \
+ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" -DRUNTIME_DIR=\"$(runtimedir)\" -DABSTRACT_SOCKET=\"$(abstract_socket)\" -DPATHNAME_SOCKET=\"$(pathname_socket)\" \
-MMD -MP
BIN_CFLAGS = -fPIE -DPIE
LIB_CFLAGS = -fPIC
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
index 146e790d..54143fb1 100644
--- a/libmpathcmd/mpath_cmd.c
+++ b/libmpathcmd/mpath_cmd.c
@@ -113,7 +113,7 @@ int __mpath_connect(int nonblocking)
(void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
}
- len = mpath_fill_sockaddr__(&addr, DEFAULT_SOCKET);
+ len = mpath_fill_sockaddr__(&addr, ABSTRACT_SOCKET);
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
int err = errno;
diff --git a/multipathd/main.c b/multipathd/main.c
index 01903914..e44df6b6 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1751,13 +1751,14 @@ uxlsnrloop (void * ap)
pthread_cleanup_push(rcu_unregister, NULL);
rcu_register_thread();
- num = get_systemd_sockets(&ux_sock);
+ num = get_systemd_sockets(ux_sock);
if (num < 1) {
- ux_sock[0] = ux_socket_listen(DEFAULT_SOCKET);
- num = 1;
+ ux_sock[0] = ux_socket_listen(ABSTRACT_SOCKET);
+ ux_sock[1] = ux_socket_listen(PATHNAME_SOCKET);
+ num = 2;
}
- if (ux_sock[0] == -1) {
- condlog(1, "could not create uxsock: %d", errno);
+ if (ux_sock[0] == -1 && ux_sock[1] == -1) {
+ condlog(1, "could not create sockets: %d", errno);
exit_daemon();
goto out;
}

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 12 Feb 2025 20:45:11 +0100
Subject: [PATCH] libmpathcmd: try both abstract and pathname sockets
When connecting to the multipathd socket, try the pathname socket
first, then the abstract socket. Fail only if both connection attempts
fail.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmpathcmd/mpath_cmd.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
index 54143fb1..267e3dd7 100644
--- a/libmpathcmd/mpath_cmd.c
+++ b/libmpathcmd/mpath_cmd.c
@@ -102,7 +102,10 @@ int __mpath_connect(int nonblocking)
size_t len;
struct sockaddr_un addr;
int flags = 0;
+ const char *const names[2] = {PATHNAME_SOCKET, ABSTRACT_SOCKET};
+ int name_idx = 0;
+retry:
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd == -1)
return -1;
@@ -113,13 +116,17 @@ int __mpath_connect(int nonblocking)
(void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
}
- len = mpath_fill_sockaddr__(&addr, ABSTRACT_SOCKET);
+ len = mpath_fill_sockaddr__(&addr, names[name_idx]);
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
int err = errno;
close(fd);
- errno = err;
- return -1;
+ if (++name_idx == 1)
+ goto retry;
+ else {
+ errno = err;
+ return -1;
+ }
}
if (nonblocking && flags != -1)

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 12 Feb 2025 21:17:41 +0100
Subject: [PATCH] libmpathcmd: honor MULTIPATH_SOCKET_NAME environment variable
In systemd installments, users can already override the socket names
that systemd listens on. With this patch, clients using libmpathcmd
can be customized to use a non-standard socket by setting an environment
variable.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmpathcmd/mpath_cmd.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
index 267e3dd7..7f805abb 100644
--- a/libmpathcmd/mpath_cmd.c
+++ b/libmpathcmd/mpath_cmd.c
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -104,6 +105,7 @@ int __mpath_connect(int nonblocking)
int flags = 0;
const char *const names[2] = {PATHNAME_SOCKET, ABSTRACT_SOCKET};
int name_idx = 0;
+ const char *env_name = getenv("MULTIPATH_SOCKET_NAME"), *name;
retry:
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
@@ -116,12 +118,13 @@ retry:
(void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
}
- len = mpath_fill_sockaddr__(&addr, names[name_idx]);
+ name = env_name ? env_name : names[name_idx];
+ len = mpath_fill_sockaddr__(&addr, name);
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
int err = errno;
close(fd);
- if (++name_idx == 1)
+ if (name != env_name && ++name_idx == 1)
goto retry;
else {
errno = err;

View File

@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 14 Feb 2025 22:18:06 +0100
Subject: [PATCH] multipathd: honor MULTIPATH_SOCKET_NAME environment variable
If multipathd is started via socket activation, it will obtain
sockets from systemd. The names of these sockets, and whether
the abstract and / or pathname socket is created, is configurable
in the systemd unit file.
Add support for passing a socket name via the environment, so that
it's possible to configure the socket name at runtime even without
socket activation. In this case, only this single socket will be created.
If creating the socket fails, multipathd startup will fail, too.
Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/main.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/multipathd/main.c b/multipathd/main.c
index e44df6b6..820d4e68 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1747,11 +1747,16 @@ uxlsnrloop (void * ap)
{
long ux_sock[2] = {-1, -1};
int num;
+ const char *env_name = getenv("MULTIPATH_SOCKET_NAME");
pthread_cleanup_push(rcu_unregister, NULL);
rcu_register_thread();
num = get_systemd_sockets(ux_sock);
+ if (num < 1 && env_name != NULL) {
+ ux_sock[0] = ux_socket_listen(env_name);
+ num = 1;
+ }
if (num < 1) {
ux_sock[0] = ux_socket_listen(ABSTRACT_SOCKET);
ux_sock[1] = ux_socket_listen(PATHNAME_SOCKET);

View File

@ -1,6 +1,6 @@
Name: device-mapper-multipath
Version: 0.8.7
Release: 35%{?dist}
Release: 35%{?dist}.1
Summary: Tools to manage multipath devices using device-mapper
License: GPLv2
URL: http://christophe.varoqui.free.fr/
@ -137,6 +137,18 @@ Patch0124: 0124-libmultipath-add-missing-assert-to-checkers.c.patch
Patch0125: 0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch
Patch0126: 0126-libmultipath-export-udev-pthread-cleanup-functions.patch
Patch0127: 0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch
Patch0128: 0128-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch
Patch0129: 0129-multipath-tools-add-helper-mpath_fill_sockaddr__.patch
Patch0130: 0130-libmpathutil-add-support-for-Unix-pathname-sockets.patch
Patch0131: 0131-libmpathutil-move-systemd_listen_fds-support-into-mu.patch
Patch0132: 0132-multipathd-move-uxsock_trigger-to-uxlsnr.c.patch
Patch0133: 0133-multipathd-uxlsnr-use-symbolic-values-for-pollfd-ind.patch
Patch0134: 0134-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch
Patch0135: 0135-multipathd-allow-receiving-two-socket-fds-from-syste.patch
Patch0136: 0136-multipathd-listen-on-pathname-and-abstract-socket-by.patch
Patch0137: 0137-libmpathcmd-try-both-abstract-and-pathname-sockets.patch
Patch0138: 0138-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch
Patch0139: 0139-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch
# runtime
@ -340,6 +352,23 @@ fi
%{_pkgconfdir}/libdmmp.pc
%changelog
* Tue Mar 4 2025 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-35.1
- Add 0128-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch
- Add 0129-multipath-tools-add-helper-mpath_fill_sockaddr__.patch
- Add 0130-libmpathutil-add-support-for-Unix-pathname-sockets.patch
- Add 0131-libmpathutil-move-systemd_listen_fds-support-into-mu.patch
- Add 0132-multipathd-move-uxsock_trigger-to-uxlsnr.c.patch
- Add 0133-multipathd-uxlsnr-use-symbolic-values-for-pollfd-ind.patch
- Add 0134-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch
- Add 0135-multipathd-allow-receiving-two-socket-fds-from-syste.patch
- Add 0136-multipathd-listen-on-pathname-and-abstract-socket-by.patch
- Add 0137-libmpathcmd-try-both-abstract-and-pathname-sockets.patch
- Add 0138-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch
- Add 0139-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch
* Fixes RHEL-80352 ("RFE: Enable multipathd to communicate with a
process in another network namespace")
- Resolves: RHEL-80352
* Thu Jan 9 2025 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-35
- Add 0124-libmultipath-add-missing-assert-to-checkers.c.patch
- Add 0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch