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

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