diff --git a/SOURCES/0128-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch b/SOURCES/0128-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch new file mode 100644 index 0000000..05d5c07 --- /dev/null +++ b/SOURCES/0128-multipath-tools-move-DEFAULT_SOCKET-definition-into-.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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" diff --git a/SOURCES/0129-multipath-tools-add-helper-mpath_fill_sockaddr__.patch b/SOURCES/0129-multipath-tools-add-helper-mpath_fill_sockaddr__.patch new file mode 100644 index 0000000..0aacbb4 --- /dev/null +++ b/SOURCES/0129-multipath-tools-add-helper-mpath_fill_sockaddr__.patch @@ -0,0 +1,157 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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 + #include + #include ++#include + #include + #include + #include + + #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 + #include ++#include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -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); diff --git a/SOURCES/0130-libmpathutil-add-support-for-Unix-pathname-sockets.patch b/SOURCES/0130-libmpathutil-add-support-for-Unix-pathname-sockets.patch new file mode 100644 index 0000000..e6a0a4c --- /dev/null +++ b/SOURCES/0130-libmpathutil-add-support-for-Unix-pathname-sockets.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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); diff --git a/SOURCES/0131-libmpathutil-move-systemd_listen_fds-support-into-mu.patch b/SOURCES/0131-libmpathutil-move-systemd_listen_fds-support-into-mu.patch new file mode 100644 index 0000000..e122a3c --- /dev/null +++ b/SOURCES/0131-libmpathutil-move-systemd_listen_fds-support-into-mu.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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(); diff --git a/SOURCES/0132-multipathd-move-uxsock_trigger-to-uxlsnr.c.patch b/SOURCES/0132-multipathd-move-uxsock_trigger-to-uxlsnr.c.patch new file mode 100644 index 0000000..44dba29 --- /dev/null +++ b/SOURCES/0132-multipathd-move-uxsock_trigger-to-uxlsnr.c.patch @@ -0,0 +1,156 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Signed-off-by: Benjamin Marzinski +--- + 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 + +-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 diff --git a/SOURCES/0133-multipathd-uxlsnr-use-symbolic-values-for-pollfd-ind.patch b/SOURCES/0133-multipathd-uxlsnr-use-symbolic-values-for-pollfd-ind.patch new file mode 100644 index 0000000..75efdcb --- /dev/null +++ b/SOURCES/0133-multipathd-uxlsnr-use-symbolic-values-for-pollfd-ind.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Signed-off-by: Benjamin Marzinski +--- + 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); + } + diff --git a/SOURCES/0134-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch b/SOURCES/0134-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch new file mode 100644 index 0000000..7debf41 --- /dev/null +++ b/SOURCES/0134-multipathd-make-uxsock_listen-take-a-pointer-to-fd.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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 + + 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 diff --git a/SOURCES/0135-multipathd-allow-receiving-two-socket-fds-from-syste.patch b/SOURCES/0135-multipathd-allow-receiving-two-socket-fds-from-syste.patch new file mode 100644 index 0000000..c7f4f7a --- /dev/null +++ b/SOURCES/0135-multipathd-allow-receiving-two-socket-fds-from-syste.patch @@ -0,0 +1,188 @@ +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) diff --git a/SOURCES/0136-multipathd-listen-on-pathname-and-abstract-socket-by.patch b/SOURCES/0136-multipathd-listen-on-pathname-and-abstract-socket-by.patch new file mode 100644 index 0000000..312bd35 --- /dev/null +++ b/SOURCES/0136-multipathd-listen-on-pathname-and-abstract-socket-by.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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; + } diff --git a/SOURCES/0137-libmpathcmd-try-both-abstract-and-pathname-sockets.patch b/SOURCES/0137-libmpathcmd-try-both-abstract-and-pathname-sockets.patch new file mode 100644 index 0000000..e592eee --- /dev/null +++ b/SOURCES/0137-libmpathcmd-try-both-abstract-and-pathname-sockets.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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) diff --git a/SOURCES/0138-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch b/SOURCES/0138-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch new file mode 100644 index 0000000..ece2a09 --- /dev/null +++ b/SOURCES/0138-libmpathcmd-honor-MULTIPATH_SOCKET_NAME-environment-.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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; diff --git a/SOURCES/0139-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch b/SOURCES/0139-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch new file mode 100644 index 0000000..d21c2ed --- /dev/null +++ b/SOURCES/0139-multipathd-honor-MULTIPATH_SOCKET_NAME-environment-v.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +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 +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + 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); diff --git a/SOURCES/0140-multipath-clean-up-find_multipaths-value-names.patch b/SOURCES/0140-multipath-clean-up-find_multipaths-value-names.patch new file mode 100644 index 0000000..b6b2288 --- /dev/null +++ b/SOURCES/0140-multipath-clean-up-find_multipaths-value-names.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 13 Mar 2025 16:08:45 -0400 +Subject: [PATCH] multipath: clean up find_multipaths value names + +The preferred term is "on" instead of "yes". + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 14 +++++++------- + multipath/multipath.conf.5 | 14 ++++++++------ + 2 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index 319664b1..ce430075 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -31,7 +31,7 @@ DEFAULT_CONFIG="# device-mapper-multipath configuration file + + defaults { + user_friendly_names yes +- find_multipaths yes ++ find_multipaths on + }" + + CONFIGFILE="/etc/multipath.conf" +@@ -49,7 +49,7 @@ function usage + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " +- echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set find_multipaths (Default on): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Set recheck_wwid (Defaut n): --recheck_wwid " +@@ -253,11 +253,11 @@ function validate_args + exit 1 + fi + if [ "$FIND" = "y" ]; then +- FIND="yes" ++ FIND="on" + elif [ "$FIND" = "n" ]; then +- FIND="no" +- elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then +- echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" ++ FIND="off" ++ elif [ -n "$FIND" ] && [ "$FIND" != "on" -a "$FIND" != "yes" -a "$FIND" != "off" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'on' 'yes' 'y' 'off' 'no' 'n' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then +@@ -422,7 +422,7 @@ if [ -n "$SHOW_STATUS" ]; then + echo "multipath is disabled" + fi + if [ -z "$HAVE_FIND" ]; then +- echo "find_multipaths is no" ++ echo "find_multipaths is off" + else + echo "find_multipaths is $HAVE_FIND" + fi +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 10eddc0c..8684bd63 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1159,22 +1159,24 @@ listed in the \fBwwids_file\fR. Users can manually set up multipath maps using t + \fBmultipathd add map\fR command. Once set up manually, the map is + remembered in the wwids file and will be set up automatically in the future. + .TP +-.I no ++.I off + Multipath behaves like \fBstrict\fR. Multipathd behaves like \fBgreedy\fR. ++\fIno\fR or \fI0\fR is accepted as an alias for \fIoff\fR. + .TP +-.I yes ++.I on + Both multipathd and multipath treat a device as multipath device if the + conditions for \fBstrict\fR are met, or if at least two non-blacklisted paths +-with the same WWID have been detected. ++with the same WWID have been detected. \fIyes\fR or \fI1\fR is accepted as an ++alias for \fIon\fR. + .TP + .I greedy + Both multipathd and multipath treat every non-blacklisted device as multipath + device path. + .TP + .I smart +-This differs from \fIfind_multipaths yes\fR only in ++This differs from \fIfind_multipaths on\fR only in + the way it treats new devices for which only one path has been +-detected yet. When such a device is first encounted in udev rules, it is ++detected yet. When such a device is first encountered in udev rules, it is + treated as a multipath device. multipathd waits whether additional paths with + the same WWID appears. If that happens, it sets up a multipath map. If it + doesn\'t happen until a +@@ -1184,7 +1186,7 @@ as non-multipath and passed on to upper layers. + \fBNote:\fR this may cause delays during device detection if + there are single-path devices which aren\'t blacklisted. + .TP +-The default is: \fBstrict\fR ++The default is: \fBoff\fR + .RE + . + . diff --git a/SOURCES/0141-multipathd-Add-multipathd-man-page-section-about-soc.patch b/SOURCES/0141-multipathd-Add-multipathd-man-page-section-about-soc.patch new file mode 100644 index 0000000..28262de --- /dev/null +++ b/SOURCES/0141-multipathd-Add-multipathd-man-page-section-about-soc.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 6 Mar 2025 18:52:02 -0500 +Subject: [PATCH] multipathd: Add multipathd man page section about sockets + +Add a section with information about how to communicate with the +multipathd daemon to the man page. Also mention that multipathd +commands can be run directly from the command line. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/multipathd.8 | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index d834f89e..d3aa7a73 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -68,6 +68,18 @@ bindings file. If a \fIuser_friendly_name\fR doesn't already exist for a device, + will use its WWID as its alias. + . + .TP ++.B \-k\fIcommand\fB ++multipathd executes the given command (see \fBCOMMANDS\fR below). If the ++command contains whitespace or shell special characters, it needs to be quoted ++like in \fImultipathd -k'show topology'\fR. No whitespace is allowed between ++the \fB-k\fR and the command string. ++ ++Commands can also be issued without using \fB-k\fR. In this case, the command ++string should not be quoted. Command arguments that contain whitespace or ++special characters still need to be quoted, like in \fImultipathd show paths ++format "%n %w"\fR ++. ++.TP + .B \-k + multipathd will enter interactive mode. From this mode, the available commands can + be viewed by entering '\fIhelp\fR'. When you are finished entering commands, press +@@ -87,6 +99,33 @@ multipath devices on dmevents. Use this flag to force it to use the old event + waiting method, based on creating a seperate thread for each device. + . + . ++.\" ---------------------------------------------------------------------------- ++.SH COMMUNICATING WITH MULTIPATHD ++.\" ---------------------------------------------------------------------------- ++ ++In addition to the multipathd CLI, the \fBlibmpathcmd\fR library can be used to ++send commands (see \fBCOMMANDS\fR below) to the multipathd daemon from other ++programs. By default, multipathd listens on both the ++\fI@/org/kernel/linux/storage/multipathd\fR abstract namespace socket and the ++\fI/run/multipathd.socket\fR socket file. libmpathcmd will use either of these ++sockets to connect to multipathd. The socket file can be useful to communicate ++with multipathd from different namespaces since it can be bind mounted in them, ++unlike the abstract namespace socket. Multipathd will accept \fBlist|show\fR ++commands from any user. All other commands must be issued by root. ++ ++It is possible to change the sockets that multipathd listens on. If ++\fImultipathd.socket\fR is running, multipathd will use the sockets it listens ++on. A maximum of two sockets can be defined by \fImultipathd.socket\fR, and by ++default it listens on \fI@/org/kernel/linux/storage/multipathd\fR and ++\fI/run/multipathd.socket\fR. If \fImultipathd.socket\fR is not running, a ++single socket can be configured for listening on by setting the ++\fIMULTIPATH_SOCKET_NAME\fR environment variable when starting multipathd. This ++environment variable must also be set to make multipathd CLI commands (or any ++other program using libmpathcmd) connect to the multipathd daemon using a ++non-default socket, regardless of whether that socket was set for the daemon ++using \fImultipathd.socket\fR or the \fIMULTIPATH_SOCKET_NAME\fR environment ++variable. ++. + . + .\" ---------------------------------------------------------------------------- + .SH COMMANDS diff --git a/SOURCES/0142-multipathd-monitor-new-multipath-dev-even-if-we-can-.patch b/SOURCES/0142-multipathd-monitor-new-multipath-dev-even-if-we-can-.patch new file mode 100644 index 0000000..a240061 --- /dev/null +++ b/SOURCES/0142-multipathd-monitor-new-multipath-dev-even-if-we-can-.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Apr 2025 19:13:19 -0400 +Subject: [PATCH] multipathd: monitor new multipath dev even if we can't update + it + +If a multipath device was created by the multipath command, multipathd +might not agree with how the device was created. ev_add_map() can reload +the device with a different table by calling add_map_without_path() -> +update_map(). If this reloading of the map failed, multipathd was simply +ignoring the multipath device, even though it still existed. + +One way that reloading can fail is if a path that multipathd already has +initialized goes offline. If a multipath device is created by the +multipath command while the path is offline, it will not use the offline +path, since multipath won't be able to get the necessary pathinfo. +However, multipathd will already have the pathinfo for the path, and may +not even know that it's offline, since the path is an orphan. When it +tries to reload the device, it will include the offline path, and the +reload will fail. + +Instead of ignoring the device if it can't reload it, multipathd should +just montior it as it is. When the path device is no longer offline, it +can be added back to the multipath device by calling +"multipathd reconfigure" or "multipathd add path ". + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 820d4e68..c5f458b9 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -593,7 +593,7 @@ retry: + } + + fail: +- if (new_map && (retries < 0 || wait_for_events(mpp, vecs))) { ++ if (new_map && wait_for_events(mpp, vecs)) { + condlog(0, "%s: failed to create new map", mpp->alias); + remove_map(mpp, vecs->pathvec, vecs->mpvec); + return 1; diff --git a/SOURCES/0143-libmultipath-add-helper-function-check_path_wwid_cha.patch b/SOURCES/0143-libmultipath-add-helper-function-check_path_wwid_cha.patch new file mode 100644 index 0000000..4568393 --- /dev/null +++ b/SOURCES/0143-libmultipath-add-helper-function-check_path_wwid_cha.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Apr 2025 19:13:20 -0400 +Subject: [PATCH] libmultipath: add helper function check_path_wwid_change + +Wrap some code from select_recheck_wwid() in a helper function. A future +patch will call this code from a different function. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/discovery.c | 13 ++++++++++++- + libmultipath/discovery.h | 2 +- + libmultipath/propsel.c | 4 +--- + 3 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 672c783b..22d114b3 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2184,7 +2184,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, + return len; + } + +-bool has_uid_fallback(struct path *pp) ++static bool has_uid_fallback(const struct path *pp) + { + /* + * Falling back to direct WWID determination is dangerous +@@ -2205,6 +2205,17 @@ bool has_uid_fallback(struct path *pp) + !strcmp(pp->uid_attribute, "")))); + } + ++bool can_recheck_wwid(const struct path *pp) ++{ ++ /* ++ * check_path_wwid_change() only works for scsi devices, and it ++ * is only guaranteed to give the same WWID if the path uses ++ * the default uid_attribute ++ */ ++ return (pp->bus == SYSFS_BUS_SCSI && !pp->getuid && ++ has_uid_fallback(pp)); ++} ++ + int + get_uid (struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback) +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index c2a88686..c7f1becd 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -54,7 +54,7 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, + unsigned char *buff, size_t len); + int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); +-bool has_uid_fallback(struct path *pp); ++bool can_recheck_wwid(const struct path *pp); + int get_uid(struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback); + bool is_vpd_page_supported(int fd, int pg); +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index be781ff7..0b6e22c1 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -672,9 +672,7 @@ int select_recheck_wwid(struct config *conf, struct path * pp) + pp_set_conf(recheck_wwid); + pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID); + out: +- if (pp->recheck_wwid == RECHECK_WWID_ON && +- (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL || +- !has_uid_fallback(pp))) { ++ if (pp->recheck_wwid == RECHECK_WWID_ON && !can_recheck_wwid(pp)) { + pp->recheck_wwid = RECHECK_WWID_OFF; + origin = "(setting: unsupported by device type/config)"; + } diff --git a/SOURCES/0144-multipathd-re-add-paths-skipped-because-they-were-of.patch b/SOURCES/0144-multipathd-re-add-paths-skipped-because-they-were-of.patch new file mode 100644 index 0000000..0a04577 --- /dev/null +++ b/SOURCES/0144-multipathd-re-add-paths-skipped-because-they-were-of.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Apr 2025 19:13:21 -0400 +Subject: [PATCH] multipathd: re-add paths skipped because they were offline + +When a new device is added by the multipath command, multipathd may know +of other paths that cannot be added to the device because they are +currently offline. Instead of ignoring these paths, multipathd will now +re-add them when they come back online. To do this, it multipathd needs +a new path variable add_when_online, to track devices that could not be +added to an existing multipath device because they were offline. These +paths are handled along with the other uninitialized paths. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/libmultipath.version | 5 +++ + libmultipath/print.c | 5 ++- + libmultipath/structs.h | 1 + + libmultipath/structs_vec.c | 5 +++ + multipathd/main.c | 53 ++++++++++++++++++++++++++++++- + multipathd/multipathd.8 | 4 ++- + 6 files changed, 70 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index e2cce8c7..46907278 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -313,3 +313,8 @@ global: + cleanup_udev_enumerate_ptr; + cleanup_udev_device_ptr; + } LIBMULTIPATH_9.1.3; ++ ++LIBMULTIPATH_9.1.5 { ++global: ++ can_recheck_wwid; ++} LIBMULTIPATH_9.1.4; +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 4552fd43..ff224bc4 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -584,8 +584,11 @@ snprint_path_serial (struct strbuf *buff, const struct path * pp) + static int + snprint_path_mpp (struct strbuf *buff, const struct path * pp) + { +- if (!pp->mpp) ++ if (!pp->mpp) { ++ if (pp->add_when_online) ++ return append_strbuf_str(buff, "[offline]"); + return append_strbuf_str(buff, "[orphan]"); ++ } + if (!pp->mpp->alias) + return append_strbuf_str(buff, "[unknown]"); + return snprint_str(buff, pp->mpp->alias); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 4bf8c93a..0846e833 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -374,6 +374,7 @@ struct path { + unsigned int dev_loss; + int eh_deadline; + bool can_use_env_uid; ++ bool add_when_online; + /* configlet pointers */ + vector hwe; + struct gen_path generic_path; +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index b8e304e0..7086781a 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -319,6 +319,9 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) + free_path(pp); + } else + orphan_path(pp, reason); ++ } else if (pp->add_when_online && ++ strncmp(mpp->wwid, pp->wwid, WWID_SIZE) == 0) { ++ pp->add_when_online = false; + } + } + } +@@ -496,6 +499,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) + found = 0; + vector_foreach_slot(mpp->pg, pgp, j) { + if (find_slot(pgp->paths, (void *)pp) != -1) { ++ if (pp->add_when_online) ++ pp->add_when_online = false; + found = 1; + break; + } +diff --git a/multipathd/main.c b/multipathd/main.c +index c5f458b9..4119ad79 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -558,11 +558,44 @@ pr_register_active_paths(struct multipath *mpp) + } + } + ++static void ++save_offline_paths(const struct multipath *mpp, vector offline_paths) ++{ ++ unsigned int i, j; ++ struct path *pp; ++ struct pathgroup *pgp; ++ ++ vector_foreach_slot (mpp->pg, pgp, i) ++ vector_foreach_slot (pgp->paths, pp, j) ++ if (pp->initialized == INIT_OK && pp->offline) ++ /* ignore failures storing the paths. */ ++ store_path(offline_paths, pp); ++} ++ ++static void ++handle_orphaned_offline_paths(vector offline_paths) ++{ ++ unsigned int i; ++ struct path *pp; ++ ++ vector_foreach_slot (offline_paths, pp, i) ++ if (pp->mpp == NULL) ++ pp->add_when_online = true; ++} ++ ++static void ++cleanup_reset_vec(struct _vector **v) ++{ ++ vector_reset(*v); ++} ++ + static int + update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; ++ struct _vector offline_paths_vec = { .allocated = 0 }; ++ vector offline_paths __attribute__((cleanup(cleanup_reset_vec))) = &offline_paths_vec; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -599,6 +632,9 @@ fail: + return 1; + } + ++ if (new_map && retries < 0) ++ save_offline_paths(mpp, offline_paths); ++ + if (setup_multipath(vecs, mpp)) + return 1; + +@@ -609,6 +645,9 @@ fail: + if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); + ++ if (VECTOR_SIZE(offline_paths) != 0) ++ handle_orphaned_offline_paths(offline_paths); ++ + if (retries < 0) + condlog(0, "%s: failed reload in new map update", mpp->alias); + return 0; +@@ -2253,7 +2292,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + int ret; + + if (((pp->initialized == INIT_OK || +- pp->initialized == INIT_REQUESTED_UDEV) && !pp->mpp) || ++ pp->initialized == INIT_REQUESTED_UDEV) && !pp->mpp && ++ !pp->add_when_online) || + pp->initialized == INIT_REMOVED) + return 0; + +@@ -2367,6 +2407,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + */ + pp->checkint = max_checkint; + } ++ } else if (pp->initialized == INIT_OK && pp->add_when_online && ++ (newstate == PATH_UP || newstate == PATH_GHOST)) { ++ pp->add_when_online = false; ++ if (can_recheck_wwid(pp) && ++ check_path_wwid_change(pp)) { ++ condlog(0, "%s: path wwid change detected. Removing", pp->dev); ++ handle_path_wwid_change(pp, vecs); ++ return 0; ++ } ++ ev_add_path(pp, vecs, 1); ++ pp->tick = 1; + } + return 0; + } +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index d3aa7a73..2ed036d4 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -529,7 +529,9 @@ The device serial number. + The device marginal state, either \fImarginal\fR or \fInormal\fR. + .TP + .B %m +-The multipath device that this device is a path of. ++The multipath device that this device is a path of, or \fI[offline]\fR ++if this device could not be added to a device because it is offline or ++\fI[orphan]\fR if it is not part of any multipath device. + .TP + .B %N + The host World Wide Node Name (WWNN) of the device. diff --git a/SOURCES/0145-multipath-tools-add-DellEMC-ME4-PowerVault-ME4-to-ha.patch b/SOURCES/0145-multipath-tools-add-DellEMC-ME4-PowerVault-ME4-to-ha.patch new file mode 100644 index 0000000..b03d5cd --- /dev/null +++ b/SOURCES/0145-multipath-tools-add-DellEMC-ME4-PowerVault-ME4-to-ha.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 29 Sep 2021 18:41:36 +0200 +Subject: [PATCH] multipath-tools: add DellEMC/ME4 (PowerVault ME4) to hardware + table + +Info from: https://www.delltechnologies.com/asset/fr-fr/products/storage/industry-market/PowerVault_ME4_Series_and_Linux.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 94012d50..d493a5ce 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -405,6 +405,15 @@ static struct hwentry default_hw[] = { + .no_path_retry = 3, + .fast_io_fail = 15, + }, ++ { ++ /* PowerVault ME4 */ ++ .vendor = "DellEMC", ++ .product = "ME4", ++ .pgpolicy = GROUP_BY_PRIO, ++ .prio_name = PRIO_ALUA, ++ .hwhandler = "1 alua", ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ }, + /* + * Fujitsu + */ diff --git a/SOURCES/0146-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch b/SOURCES/0146-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch new file mode 100644 index 0000000..aa22145 --- /dev/null +++ b/SOURCES/0146-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 24 Feb 2022 22:23:34 +0100 +Subject: [PATCH] multipath-tools: add HPE as vendor for OPEN- (XP8 arrays) + +Cc: Matthias Rudolph +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index d493a5ce..d556f25d 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -476,8 +476,8 @@ static struct hwentry default_hw[] = { + * Maintainer: Matthias Rudolph + */ + { +- /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HP XP */ +- .vendor = "(HITACHI|HP)", ++ /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HPE XP */ ++ .vendor = "(HITACHI|HP|HPE)", + .product = "^OPEN-", + .pgpolicy = MULTIBUS, + }, diff --git a/SOURCES/0147-multipath-tools-add-HP-HSVX740-to-hwtable.patch b/SOURCES/0147-multipath-tools-add-HP-HSVX740-to-hwtable.patch new file mode 100644 index 0000000..7a33aa3 --- /dev/null +++ b/SOURCES/0147-multipath-tools-add-HP-HSVX740-to-hwtable.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 24 Feb 2022 22:24:39 +0100 +Subject: [PATCH] multipath-tools: add HP/HSVX740 to hwtable + +Info from: https://community.hpe.com/hpeb/attachments/hpeb/itrc-248/61618/1/HP_DM_MP_Guide.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index d556f25d..487bce8e 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -200,7 +200,7 @@ static struct hwentry default_hw[] = { + { + /* SAN Virtualization Services Platform */ + .vendor = "HP", +- .product = "HSVX700", ++ .product = "(HSVX700|HSVX740)", + .hwhandler = "1 alua", + .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, diff --git a/SOURCES/0148-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch b/SOURCES/0148-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch new file mode 100644 index 0000000..49e572f --- /dev/null +++ b/SOURCES/0148-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 23 Feb 2022 23:16:44 +0100 +Subject: [PATCH] multipath-tools: add DellEMC/ME5 (PowerVault ME5) to hardware + table + +Convert PowerVault ME4 template for all ME series. + +[MW] https://dl.dell.com/content/manual51886263-dell-powervault-me5-series-administrator's-guide.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 487bce8e..e5575a31 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -406,9 +406,9 @@ static struct hwentry default_hw[] = { + .fast_io_fail = 15, + }, + { +- /* PowerVault ME4 */ ++ /* PowerVault ME 4/5 families */ + .vendor = "DellEMC", +- .product = "ME4", ++ .product = "^ME", + .pgpolicy = GROUP_BY_PRIO, + .prio_name = PRIO_ALUA, + .hwhandler = "1 alua", diff --git a/SOURCES/0149-multipath-tools-add-HPE-MSA-Gen7-2070-2072-to-hwtabl.patch b/SOURCES/0149-multipath-tools-add-HPE-MSA-Gen7-2070-2072-to-hwtabl.patch new file mode 100644 index 0000000..f6d1f24 --- /dev/null +++ b/SOURCES/0149-multipath-tools-add-HPE-MSA-Gen7-2070-2072-to-hwtabl.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 5 Dec 2024 23:49:16 +0100 +Subject: [PATCH] multipath-tools: add HPE MSA Gen7 (2070/2072) to hwtable + +https://support.hpe.com/connect/s/product?kmpmoid=1014856412 + +Just guessing, confirmation from manufacturer is needed. + +Cc: Jon Paul +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Acked-by: Jon Paul +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index e5575a31..2d359829 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -189,9 +189,9 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + }, + { +- /* MSA 1040, 1050, 1060, 2040, 2050 and 2060 families */ ++ /* MSA 1040, 1050, 1060, 2040, 2050, 2060 and 2070 families */ + .vendor = "(HP|HPE)", +- .product = "MSA [12]0[456]0 (SAN|SAS|FC|iSCSI)", ++ .product = "MSA [12]0[4567]0 (SAN|SAS|FC|iSCSI)", + .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, + .no_path_retry = 18, diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 6b4c2f1..a2d9752 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 35%{?dist} +Release: 39%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -137,6 +137,28 @@ 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 +Patch0140: 0140-multipath-clean-up-find_multipaths-value-names.patch +Patch0141: 0141-multipathd-Add-multipathd-man-page-section-about-soc.patch +Patch0142: 0142-multipathd-monitor-new-multipath-dev-even-if-we-can-.patch +Patch0143: 0143-libmultipath-add-helper-function-check_path_wwid_cha.patch +Patch0144: 0144-multipathd-re-add-paths-skipped-because-they-were-of.patch +Patch0145: 0145-multipath-tools-add-DellEMC-ME4-PowerVault-ME4-to-ha.patch +Patch0146: 0146-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch +Patch0147: 0147-multipath-tools-add-HP-HSVX740-to-hwtable.patch +Patch0148: 0148-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch +Patch0149: 0149-multipath-tools-add-HPE-MSA-Gen7-2070-2072-to-hwtabl.patch # runtime @@ -340,6 +362,49 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jul 14 2025 Benjamin Marzinski - 0.8.7-39 +- Add 0145-multipath-tools-add-DellEMC-ME4-PowerVault-ME4-to-ha.patch +- Add 0146-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch +- Add 0147-multipath-tools-add-HP-HSVX740-to-hwtable.patch +- Add 0148-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch +- Add 0149-multipath-tools-add-HPE-MSA-Gen7-2070-2072-to-hwtabl.patch + * Fixes RHEL-103109 ("Update multipath builtin config to add new + device defaults") +- Resolves: RHEL-103109 + +* Thu Apr 17 2025 Benjamin Marzinski - 0.8.7-38 +- Add 0142-multipathd-monitor-new-multipath-dev-even-if-we-can-.patch +- Add 0143-libmultipath-add-helper-function-check_path_wwid_cha.patch +- Add 0144-multipathd-re-add-paths-skipped-because-they-were-of.patch + * Fixes RHEL-82534 ("multipathd does not monitor multipath devices + created externally while there are offline paths.") +- Resolves: RHEL-82534 + +* Thu Mar 13 2025 Benjamin Marzinski - 0.8.7-37 +- Add 0140-multipath-clean-up-find_multipaths-value-names.patch +- Add 0141-multipathd-Add-multipathd-man-page-section-about-soc.patch + * Fixes RHEL-82307 ("There is no man page for RFE: Enable multipathd + to communicate with a process in another network namespace") +- Fix multipath_conf_syntax OSCI test. +- Resolves: RHEL-82307 + +* Tue Mar 4 2025 Benjamin Marzinski - 0.8.7-36 +- 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-78758 ("RFE: Enable multipathd to communicate with a + process in another network namespace") +- Resolves: RHEL-78758 + * Thu Jan 9 2025 Benjamin Marzinski - 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