Blame SOURCES/0040-libmultipath-limit-reading-0xc9-vpd-page.patch

60b218
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
60b218
From: Benjamin Marzinski <bmarzins@redhat.com>
60b218
Date: Wed, 7 Oct 2020 21:43:02 -0500
60b218
Subject: [PATCH] libmultipath: limit reading 0xc9 vpd page
60b218
60b218
Only rdac arrays support 0xC9 vpd page inquiries. All other arrays will
60b218
return a failure. Only do the rdac inquiry when detecting array
60b218
capabilities if the array's path checker is explicitly set to rdac, or
60b218
the path checker is not set, and the array reports that it supports vpd
60b218
page 0xC9 in the Supported VPD Pages (0x00) vpd page.
60b218
60b218
Multipath was doing the check if either the path checker was set to
60b218
rdac, or no path checker was set.  This means that for almost all
60b218
non-rdac arrays, multipath was issuing a bad inquiry. This was annoying
60b218
users.
60b218
60b218
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
60b218
---
60b218
 libmultipath/discovery.c | 25 +++++++++++++++++++++++++
60b218
 libmultipath/discovery.h |  1 +
60b218
 libmultipath/propsel.c   | 10 ++++++----
60b218
 3 files changed, 32 insertions(+), 4 deletions(-)
60b218
60b218
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
60b218
index eb1e735d..01aadba9 100644
60b218
--- a/libmultipath/discovery.c
60b218
+++ b/libmultipath/discovery.c
60b218
@@ -1266,6 +1266,31 @@ fetch_vpd_page(int fd, int pg, unsigned char *buff)
60b218
 	return buff_len;
60b218
 }
60b218
 
60b218
+/* heavily based on sg_inq.c from sg3_utils */
60b218
+bool
60b218
+is_vpd_page_supported(int fd, int pg)
60b218
+{
60b218
+	int i, len, buff_len;
60b218
+	unsigned char buff[4096];
60b218
+
60b218
+	buff_len = fetch_vpd_page(fd, 0x00, buff);
60b218
+	if (buff_len < 0)
60b218
+		return false;
60b218
+	if (buff_len < 4) {
60b218
+		condlog(3, "VPD page 00h too short");
60b218
+		return false;
60b218
+	}
60b218
+
60b218
+	len = buff[3] + 4;
60b218
+	if (len > buff_len)
60b218
+		condlog(3, "vpd page 00h trucated, expected %d, have %d",
60b218
+			len, buff_len);
60b218
+	for (i = 4; i < len; ++i)
60b218
+		if (buff[i] == pg)
60b218
+			return true;
60b218
+	return false;
60b218
+}
60b218
+
60b218
 int
60b218
 get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
60b218
 {
60b218
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
60b218
index 6444887d..d3193daf 100644
60b218
--- a/libmultipath/discovery.h
60b218
+++ b/libmultipath/discovery.h
60b218
@@ -56,6 +56,7 @@ int sysfs_get_asymmetric_access_state(struct path *pp,
60b218
 				      char *buff, int buflen);
60b218
 int get_uid(struct path * pp, int path_state, struct udev_device *udev,
60b218
 	    int allow_fallback);
60b218
+bool is_vpd_page_supported(int fd, int pg);
60b218
 
60b218
 /*
60b218
  * discovery bitmask
60b218
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
60b218
index d362beb4..d7febec6 100644
60b218
--- a/libmultipath/propsel.c
60b218
+++ b/libmultipath/propsel.c
60b218
@@ -496,13 +496,15 @@ check_rdac(struct path * pp)
60b218
 {
60b218
 	int len;
60b218
 	char buff[44];
60b218
-	const char *checker_name;
60b218
+	const char *checker_name = NULL;
60b218
 
60b218
 	if (pp->bus != SYSFS_BUS_SCSI)
60b218
 		return 0;
60b218
-	/* Avoid ioctl if this is likely not an RDAC array */
60b218
-	if (__do_set_from_hwe(checker_name, pp, checker_name) &&
60b218
-	    strcmp(checker_name, RDAC))
60b218
+	/* Avoid checking 0xc9 if this is likely not an RDAC array */
60b218
+	if (!__do_set_from_hwe(checker_name, pp, checker_name) &&
60b218
+	    !is_vpd_page_supported(pp->fd, 0xC9))
60b218
+		return 0;
60b218
+	if (checker_name && strcmp(checker_name, RDAC))
60b218
 		return 0;
60b218
 	len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44);
60b218
 	if (len <= 0)
60b218
-- 
60b218
2.17.2
60b218