From 6bb21af4f33961eb02ce749483290ddfe0b85d1c Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 11 Mar 2025 07:09:14 +0000 Subject: [PATCH] import CS device-mapper-multipath-0.8.7-35.el9 --- ...ix-ontap-prioritizer-snprintf-limits.patch | 77 +++++++++ ...checker-port_state-before-setting-it.patch | 40 +++++ ...ath-add-missing-assert-to-checkers.c.patch | 22 +++ ...eign-fix-memory-leak-in-nvme-foreign.patch | 37 +++++ ...xport-udev-pthread-cleanup-functions.patch | 64 ++++++++ ...port-port_state-to-marginal-for-NVMe.patch | 154 ++++++++++++++++++ SPECS/device-mapper-multipath.spec | 26 ++- 7 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch create mode 100644 SOURCES/0123-multipathd-checker-port_state-before-setting-it.patch create mode 100644 SOURCES/0124-libmultipath-add-missing-assert-to-checkers.c.patch create mode 100644 SOURCES/0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch create mode 100644 SOURCES/0126-libmultipath-export-udev-pthread-cleanup-functions.patch create mode 100644 SOURCES/0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch diff --git a/SOURCES/0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch b/SOURCES/0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch new file mode 100644 index 0000000..2fb3732 --- /dev/null +++ b/SOURCES/0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 7 Aug 2024 18:59:10 -0400 +Subject: [PATCH] libmultipath: fix ontap prioritizer snprintf limits + +The ontap prioritizer functions dump_cdb() and process_sg_error() both +incorrectly set the snprintf() limits larger than the available space. +Instead of multiplying the number of elements to print by the size of an +element to calculate the limit, they multiplied the number of elements +to print by the maximum number of elements that the buffer could hold. + +Fix this by making these functions use strbufs instead. + +mwilck: removed log message in print_strbuf() failure case. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Martin Wilck +--- + libmultipath/prioritizers/ontap.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/prioritizers/ontap.c b/libmultipath/prioritizers/ontap.c +index 262e69d2..80ab6ee4 100644 +--- a/libmultipath/prioritizers/ontap.c ++++ b/libmultipath/prioritizers/ontap.c +@@ -23,6 +23,7 @@ + #include "prio.h" + #include "structs.h" + #include "unaligned.h" ++#include "strbuf.h" + + #define INQUIRY_CMD 0x12 + #define INQUIRY_CMDLEN 6 +@@ -36,32 +37,29 @@ + static void dump_cdb(unsigned char *cdb, int size) + { + int i; +- char buf[10*5+1]; +- char * p = &buf[0]; ++ STRBUF_ON_STACK(buf); + +- condlog(0, "- SCSI CDB: "); +- for (i=0; imasked_status, + io_hdr->host_status, io_hdr->driver_status); + if (io_hdr->sb_len_wr > 0) { +- condlog(0, "- SCSI sense data: "); +- for (i=0; isb_len_wr; i++) { +- p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ", +- io_hdr->sbp[i]); ++ for (i = 0; i < io_hdr->sb_len_wr; i++) { ++ if (print_strbuf(&buf, "0x%02x ", io_hdr->sbp[i]) < 0) ++ return; + } +- condlog(0, "%s", buf); ++ condlog(0, "- SCSI sense data: %s", get_strbuf_str(&buf)); + } + } + diff --git a/SOURCES/0123-multipathd-checker-port_state-before-setting-it.patch b/SOURCES/0123-multipathd-checker-port_state-before-setting-it.patch new file mode 100644 index 0000000..cfbfb24 --- /dev/null +++ b/SOURCES/0123-multipathd-checker-port_state-before-setting-it.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 16 Sep 2024 19:29:13 -0400 +Subject: [PATCH] multipathd: checker port_state before setting it. + +If the rport port_state is already Marginal, trying to set it to +Marginal causes an error like the following: + +multipathd[365376]: /sys/devices/pci0000:c0/0000:c0:01.1/0000:c4:00.0/host0/rport-0:0-5/fc_remote_ports/rport-0:0-5: failed to set port_state to marginal: Invalid argument + +To avoid causing this confusing error message, check if the port_state +is already marginal before trying to set it. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/fpin_handlers.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index d5f7594d..c5b9785f 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -168,8 +168,16 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) + /*Sets the rport port_state to marginal*/ + static void fpin_set_rport_marginal(struct udev_device *rport_dev) + { ++ char old_value[20]; /* match kernel show_fc_rport_port_state() size */ ++ static const char marginal[] = "Marginal"; ++ ssize_t ret; ++ ++ ret = sysfs_attr_get_value(rport_dev, "port_state", ++ old_value, sizeof(old_value)); ++ if (ret == sizeof(marginal) - 1 && strcmp(old_value, marginal) == 0) ++ return; + sysfs_attr_set_value(rport_dev, "port_state", +- "Marginal", strlen("Marginal")); ++ marginal, sizeof(marginal) - 1); + } + + /*Add the marginal devices info into the list and return 0 on success*/ diff --git a/SOURCES/0124-libmultipath-add-missing-assert-to-checkers.c.patch b/SOURCES/0124-libmultipath-add-missing-assert-to-checkers.c.patch new file mode 100644 index 0000000..3a6f48e --- /dev/null +++ b/SOURCES/0124-libmultipath-add-missing-assert-to-checkers.c.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 17 Dec 2024 23:03:39 -0500 +Subject: [PATCH] libmultipath: add missing assert to checkers.c + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c +index 8039c2bf..9eb3e261 100644 +--- a/libmultipath/checkers.c ++++ b/libmultipath/checkers.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "checkers.h" diff --git a/SOURCES/0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/SOURCES/0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch new file mode 100644 index 0000000..faf428c --- /dev/null +++ b/SOURCES/0125-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Jan 2025 19:57:53 -0500 +Subject: [PATCH] libmultipath/foreign: fix memory leak in nvme foreign handler + +_find_controllers() needs to free the udev device if it doesn't get +added to a path. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/foreign/nvme.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index 76b57283..63ab2c62 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -707,6 +707,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + path = _find_path_by_syspath(map, + udev_device_get_syspath(udev)); + if (path != NULL) { ++ udev_device_unref(udev); + path->seen = true; + condlog(4, "%s: %s already known", + __func__, fn); +@@ -714,8 +715,10 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + } + + path = calloc(1, sizeof(*path)); +- if (path == NULL) ++ if (path == NULL) { ++ udev_device_unref(udev); + continue; ++ } + + path->gen.ops = &nvme_path_ops; + path->udev = udev; diff --git a/SOURCES/0126-libmultipath-export-udev-pthread-cleanup-functions.patch b/SOURCES/0126-libmultipath-export-udev-pthread-cleanup-functions.patch new file mode 100644 index 0000000..de0c24b --- /dev/null +++ b/SOURCES/0126-libmultipath-export-udev-pthread-cleanup-functions.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 17 Dec 2024 20:30:30 -0500 +Subject: [PATCH] libmultipath: export udev pthread cleanup functions + +A future patch will make use of cleanup_udev_enumerate_ptr() and +cleanup_udev_device_ptr(). + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 4 ++-- + libmultipath/discovery.h | 2 ++ + libmultipath/libmultipath.version | 6 ++++++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index b24594cd..672c783b 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -146,7 +146,7 @@ path_discover (vector pathvec, struct config * conf, + return pathinfo(pp, conf, flag); + } + +-static void cleanup_udev_enumerate_ptr(void *arg) ++void cleanup_udev_enumerate_ptr(void *arg) + { + struct udev_enumerate *ue; + +@@ -157,7 +157,7 @@ static void cleanup_udev_enumerate_ptr(void *arg) + (void)udev_enumerate_unref(ue); + } + +-static void cleanup_udev_device_ptr(void *arg) ++void cleanup_udev_device_ptr(void *arg) + { + struct udev_device *ud; + +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index b6eea258..c2a88686 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -58,6 +58,8 @@ bool has_uid_fallback(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); ++void cleanup_udev_enumerate_ptr(void *arg); ++void cleanup_udev_device_ptr(void *arg); + + /* + * discovery bitmask +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 40d9246d..e2cce8c7 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -307,3 +307,9 @@ LIBMULTIPATH_9.1.3 { + global: + partmap_in_use; + } LIBMULTIPATH_9.1.2; ++ ++LIBMULTIPATH_9.1.4 { ++global: ++ cleanup_udev_enumerate_ptr; ++ cleanup_udev_device_ptr; ++} LIBMULTIPATH_9.1.3; diff --git a/SOURCES/0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch b/SOURCES/0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch new file mode 100644 index 0000000..77f8175 --- /dev/null +++ b/SOURCES/0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch @@ -0,0 +1,154 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 17 Dec 2024 21:58:24 -0500 +Subject: [PATCH] multipathd: set rport port_state to marginal for NVMe devices + +When a scsi path device is set to marginal, it updates the rport state. +Do this for NVMe devices as well. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/fpin_handlers.c | 84 +++++++++++++++++++++++++++++++++++--- + 1 file changed, 78 insertions(+), 6 deletions(-) + +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index c5b9785f..f09bc8c5 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -14,6 +14,7 @@ + #include "debug.h" + #include "util.h" + #include "sysfs.h" ++#include "discovery.h" + + #include "fpin.h" + #include "devmapper.h" +@@ -248,7 +249,7 @@ static int extract_nvme_addresses_chk_path_pwwn(const char *address, + * with the els wwpn ,attached_wwpn and sets the path state to + * Marginal + */ +-static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, ++static bool fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, + uint64_t els_wwpn, uint64_t attached_wwpn) + { + struct udev_device *ctl = NULL; +@@ -258,21 +259,89 @@ static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp + ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); + if (ctl == NULL) { + condlog(2, "%s: No parent device for ", pp->dev); +- return; ++ return false; + } + address = udev_device_get_sysattr_value(ctl, "address"); + if (!address) { + condlog(2, "%s: unable to get the address ", pp->dev); +- return; ++ return false; + } + condlog(4, "\n address %s: dev :%s\n", address, pp->dev); + ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); + if (ret <= 0) +- return; ++ return false; + ret = fpin_add_marginal_dev_info(host_num, pp->dev); + if (ret < 0) +- return; ++ return false; + fpin_path_setmarginal(pp); ++ return true; ++} ++ ++/* ++ * glibc's non-destructive version of basename() ++ * License: LGPL-2.1-or-later ++ */ ++static const char *libmp_basename(const char *filename) ++{ ++ char *p = strrchr(filename, '/'); ++ return p ? p + 1 : filename; ++} ++ ++static void fpin_nvme_set_rport_marginal(uint16_t host_num, uint64_t els_wwpn) ++{ ++ struct udev_enumerate *udev_enum = NULL; ++ struct udev_list_entry *entry; ++ ++ pthread_cleanup_push(cleanup_udev_enumerate_ptr, &udev_enum); ++ udev_enum = udev_enumerate_new(udev); ++ if (!udev_enum) { ++ condlog(0, "fpin: rport udev_enumerate_new() failed: %m"); ++ goto out; ++ } ++ if (udev_enumerate_add_match_subsystem(udev_enum, "fc_remote_ports") < 0 || ++ udev_enumerate_add_match_is_initialized(udev_enum) < 0 || ++ udev_enumerate_scan_devices(udev_enum) < 0) { ++ condlog(0, "fpin: error setting up rport enumeration: %m"); ++ goto out; ++ } ++ udev_list_entry_foreach(entry, ++ udev_enumerate_get_list_entry(udev_enum)) { ++ const char *devpath; ++ const char *rport_id, *value; ++ struct udev_device *rport_dev = NULL; ++ uint16_t rport_hostnum; ++ uint64_t rport_wwpn; ++ unsigned int unused; ++ ++ pthread_cleanup_push(cleanup_udev_device_ptr, &rport_dev); ++ devpath = udev_list_entry_get_name(entry); ++ if (!devpath) ++ goto next; ++ rport_id = libmp_basename(devpath); ++ if (sscanf(rport_id, "rport-%hu:%u-%u", &rport_hostnum, &unused, ++ &unused) != 3 || rport_hostnum != host_num) ++ goto next; ++ ++ rport_dev = udev_device_new_from_syspath(udev, devpath); ++ if (!rport_dev) { ++ condlog(0, "%s: error getting rport dev: %m", rport_id); ++ goto next; ++ } ++ value = udev_device_get_sysattr_value(rport_dev, "port_name"); ++ if (!value) { ++ condlog(0, "%s: error getting port_name: %m", rport_id); ++ goto next; ++ } ++ ++ rport_wwpn = strtol(value, NULL, 16); ++ /* If the rport wwpn matches, set the port state to marginal */ ++ if (rport_wwpn == els_wwpn) ++ fpin_set_rport_marginal(rport_dev); ++next: ++ pthread_cleanup_pop(1); ++ } ++out: ++ pthread_cleanup_pop(1); + } + + /* +@@ -333,6 +402,7 @@ static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *ve + struct multipath *mpp; + int i, k; + int ret = 0; ++ bool found_nvme = false; + + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(&vecs->lock); +@@ -343,7 +413,7 @@ static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *ve + continue; + /*checks if the bus type is nvme and the protocol is FC-NVMe*/ + if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { +- fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); ++ found_nvme = fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn) || found_nvme; + } else if ((pp->bus == SYSFS_BUS_SCSI) && + (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && + (host_num == pp->sg_id.host_no)) { +@@ -351,6 +421,8 @@ static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *ve + fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); + } + } ++ if (found_nvme) ++ fpin_nvme_set_rport_marginal(host_num, els_wwpn); + /* walk backwards because reload_and_sync_map() can remove mpp */ + vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { + if (mpp->fpin_must_reload) { diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index d0d6117..6b4c2f1 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: 32%{?dist} +Release: 35%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -131,6 +131,12 @@ Patch0118: 0118-libmultipath-change-the-vend-prod-rev-printing.patch Patch0119: 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch Patch0120: 0120-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch Patch0121: 0121-multipathd-set-reply-length-to-zero-for-NULL-replies.patch +Patch0122: 0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch +Patch0123: 0123-multipathd-checker-port_state-before-setting-it.patch +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 # runtime @@ -334,6 +340,24 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* 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 + * Fixes RHEL-73413 +- Add 0126-libmultipath-export-udev-pthread-cleanup-functions.patch +- Add 0127-multipathd-set-rport-port_state-to-marginal-for-NVMe.patch + * Fixes RHEL-67472 +- Resolves: RHEL-73413 +- Resolves: RHEL-67472 + +* Tue Sep 17 2024 Benjamin Marzinski - 0.8.7-34 +- Add 0123-multipathd-checker-port_state-before-setting-it.patch +- Resolves: RHEL-59157 + +* Fri Sep 13 2024 Benjamin Marzinski - 0.8.7-33 +- Add 0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch +- Resolves: RHEL-58920 + * Mon Aug 5 2024 Benjamin Marzinski - 0.8.7-32 - Modify bindings, find_multipaths, and user_friendly_names tests * Fixes RHEL-28068 & RHEL-4459