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