import CS device-mapper-multipath-0.8.7-35.el9

This commit is contained in:
eabdullin 2025-03-11 07:09:14 +00:00
parent 7c7fe0d1e2
commit 6bb21af4f3
7 changed files with 419 additions and 1 deletions

View File

@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
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; i<size; i++) {
- p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
+ for (i = 0; i < size; i++) {
+ if (print_strbuf(&buf, "0x%02x ", cdb[i]) < 0)
+ return;
}
- condlog(0, "%s", buf);
+ condlog(0, "- SCSI CDB: %s", get_strbuf_str(&buf));
}
static void process_sg_error(struct sg_io_hdr *io_hdr)
{
int i;
- char buf[128*5+1];
- char * p = &buf[0];
+ STRBUF_ON_STACK(buf);
condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
"driver_status=0x%02x", io_hdr->masked_status,
io_hdr->host_status, io_hdr->driver_status);
if (io_hdr->sb_len_wr > 0) {
- condlog(0, "- SCSI sense data: ");
- for (i=0; i<io_hdr->sb_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));
}
}

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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*/

View File

@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Tue, 17 Dec 2024 23:03:39 -0500
Subject: [PATCH] libmultipath: add missing assert to checkers.c
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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 <sys/stat.h>
#include <urcu.h>
#include <urcu/uatomic.h>
+#include <assert.h>
#include "debug.h"
#include "checkers.h"

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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;

View File

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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;

View File

@ -0,0 +1,154 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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) {

View File

@ -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 <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
* 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 <bmarzins@redhat.com> - 0.8.7-34
- Add 0123-multipathd-checker-port_state-before-setting-it.patch
- Resolves: RHEL-59157
* Fri Sep 13 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-33
- Add 0122-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch
- Resolves: RHEL-58920
* Mon Aug 5 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-32
- Modify bindings, find_multipaths, and user_friendly_names tests
* Fixes RHEL-28068 & RHEL-4459