|
|
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 |
|