[PATCH v2 5/5] libmultipath: fix ALUA autodetection when paths are down

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Martin Wilck <mwilck@xxxxxxxx>

If a single path was offline when detect_alua() was called,
multipathd would assume ALUA was generally unsupported.

Fix that by assuming that if at least one path has ALUA support and
no path explicitly does not have it, ALUA is supported.

Signed-off-by: Martin Wilck <mwilck@xxxxxxxx>
Reviewed-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx>

---
 libmultipath/discovery.c | 22 +++++++++++++++++++++-
 libmultipath/propsel.c   | 20 +++++++++++++++++---
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 4288c9fd..5f41dcb7 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -871,6 +871,10 @@ get_serial (char * str, int maxlen, int fd)
 	return 1;
 }
 
+/*
+ * Side effect: sets pp->tpgs if it could be determined.
+ * If ALUA calls fail because paths are unreachable, pp->tpgs remains unchanged.
+ */
 static void
 detect_alua(struct path * pp)
 {
@@ -881,12 +885,28 @@ detect_alua(struct path * pp)
 	if (sysfs_get_timeout(pp, &timeout) <= 0)
 		timeout = DEF_TIMEOUT;
 
-	if ((tpgs = get_target_port_group_support(pp, timeout)) <= 0) {
+	tpgs = get_target_port_group_support(pp, timeout);
+	if (tpgs == -RTPG_INQUIRY_FAILED)
+		return;
+	else if (tpgs <= 0) {
 		pp->tpgs = TPGS_NONE;
 		return;
 	}
+
+	if (pp->fd == -1 || pp->offline)
+		return;
+
 	ret = get_target_port_group(pp, timeout);
 	if (ret < 0 || get_asymmetric_access_state(pp, ret, timeout) < 0) {
+		int state;
+
+		if (ret == -RTPG_INQUIRY_FAILED)
+			return;
+
+		state = path_offline(pp);
+		if (state == PATH_DOWN || state == PATH_PENDING)
+			return;
+
 		pp->tpgs = TPGS_NONE;
 		return;
 	}
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 27e8d68a..a5fc6ba0 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -432,12 +432,26 @@ int select_hwhandler(struct config *conf, struct multipath *mp)
 	static const char tpgs_origin[]= "(setting: autodetected from TPGS)";
 	char *dh_state;
 	int i;
-	bool all_tpgs = true;
+	bool all_tpgs = true, one_tpgs = false;
 
 	dh_state = &handler[2];
 
-	vector_foreach_slot(mp->paths, pp, i)
-		all_tpgs = all_tpgs && (path_get_tpgs(pp) > 0);
+	/*
+	 * TPGS_UNDEF means that ALUA support couldn't determined either way
+	 * yet, probably because the path was always down.
+	 * If at least one path does have TPGS support, and no path has
+	 * TPGS_NONE, assume that TPGS would be supported by all paths if
+	 * all were up.
+	 */
+	vector_foreach_slot(mp->paths, pp, i) {
+		int tpgs = path_get_tpgs(pp);
+
+		all_tpgs = all_tpgs && tpgs != TPGS_NONE;
+		one_tpgs = one_tpgs ||
+			(tpgs != TPGS_NONE && tpgs != TPGS_UNDEF);
+	}
+	all_tpgs = all_tpgs && one_tpgs;
+
 	if (mp->retain_hwhandler != RETAIN_HWHANDLER_OFF) {
 		vector_foreach_slot(mp->paths, pp, i) {
 			if (get_dh_state(pp, dh_state, sizeof(handler) - 2) > 0
-- 
2.24.0


--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel




[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux