[dm-devel] [PATCH v3 06/10] libmultipath: lazy tpgs probing

Martin Wilck mwilck at suse.com
Mon Mar 18 11:24:41 UTC 2019


Provide a "getter" function that can be used to probe tpgs lazily.
This way we don't need to send an RTPG in the pathinfo() call
chain (e.g. in "multipath -u"). With this in place, no "user"
code should access pp->tpgs directly any more.

Moreover, in select_prio(), in the case where the alua checker
was statically configured, rather then calling into the alua
code directly, use get_tpgs(), which does all the proper error
checking, and fall back to const prio if it fails.

Signed-off-by: Martin Wilck <mwilck at suse.com>
---
 libmultipath/discovery.c | 10 +++++++---
 libmultipath/discovery.h |  2 +-
 libmultipath/propsel.c   | 25 +++++++++++++++----------
 multipathd/main.c        |  7 ++++---
 4 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index b2a43e86..b51a37b2 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -854,6 +854,13 @@ detect_alua(struct path * pp)
 	pp->tpgs = tpgs;
 }
 
+int path_get_tpgs(struct path *pp)
+{
+	if (pp->tpgs == TPGS_UNDEF)
+		detect_alua(pp);
+	return pp->tpgs;
+}
+
 #define DEFAULT_SGIO_LEN 254
 
 /* Query VPD page @pg. Returns number of INQUIRY bytes
@@ -1521,9 +1528,6 @@ scsi_ioctl_pathinfo (struct path * pp, struct config *conf, int mask)
 	struct udev_device *parent;
 	const char *attr_path = NULL;
 
-	if (pp->tpgs == TPGS_UNDEF)
-		detect_alua(pp);
-
 	if (!(mask & DI_SERIAL))
 		return;
 
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
index a9a28add..01789339 100644
--- a/libmultipath/discovery.h
+++ b/libmultipath/discovery.h
@@ -31,7 +31,7 @@
 struct config;
 
 int path_discovery (vector pathvec, int flag);
-
+int path_get_tpgs(struct path *pp); /* This function never returns TPGS_UNDEF */
 int do_tur (char *);
 int path_offline (struct path *);
 int get_state (struct path * pp, struct config * conf, int daemon, int state);
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 624dc6ef..27474f05 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -425,7 +425,7 @@ int select_hwhandler(struct config *conf, struct multipath *mp)
 	dh_state = &handler[2];
 
 	vector_foreach_slot(mp->paths, pp, i)
-		all_tpgs = all_tpgs && (pp->tpgs > 0);
+		all_tpgs = all_tpgs && (path_get_tpgs(pp) > 0);
 	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
@@ -490,7 +490,7 @@ int select_checker(struct config *conf, struct path *pp)
 		if (check_rdac(pp)) {
 			ckr_name = RDAC;
 			goto out;
-		} else if (pp->tpgs > 0) {
+		} else if (path_get_tpgs(pp) != TPGS_NONE) {
 			ckr_name = TUR;
 			goto out;
 		}
@@ -552,6 +552,7 @@ detect_prio(struct config *conf, struct path * pp)
 	struct prio *p = &pp->prio;
 	char buff[512];
 	char *default_prio;
+	int tpgs;
 
 	switch(pp->bus) {
 	case SYSFS_BUS_NVME:
@@ -560,9 +561,10 @@ detect_prio(struct config *conf, struct path * pp)
 		default_prio = PRIO_ANA;
 		break;
 	case SYSFS_BUS_SCSI:
-		if (pp->tpgs <= 0)
+		tpgs = path_get_tpgs(pp);
+		if (tpgs == TPGS_NONE)
 			return;
-		if ((pp->tpgs == 2 || !check_rdac(pp)) &&
+		if ((tpgs == TPGS_EXPLICIT || !check_rdac(pp)) &&
 		    sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
 			default_prio = PRIO_SYSFS;
 		else
@@ -607,6 +609,7 @@ int select_prio(struct config *conf, struct path *pp)
 	const char *origin;
 	struct mpentry * mpe;
 	struct prio * p = &pp->prio;
+	int log_prio = 3;
 
 	if (pp->detect_prio == DETECT_PRIO_ON) {
 		detect_prio(conf, pp);
@@ -628,14 +631,16 @@ out:
 	 * fetch tpgs mode for alua, if its not already obtained
 	 */
 	if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
-		int tpgs = 0;
-		unsigned int timeout = conf->checker_timeout;
+		int tpgs = path_get_tpgs(pp);
 
-		if(!pp->tpgs &&
-		   (tpgs = get_target_port_group_support(pp, timeout)) >= 0)
-			pp->tpgs = tpgs;
+		if (tpgs == TPGS_NONE) {
+			prio_get(conf->multipath_dir,
+				 p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
+			origin = "(setting: emergency fallback - alua failed)";
+			log_prio = 1;
+		}
 	}
-	condlog(3, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
+	condlog(log_prio, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
 	condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin);
 	return 0;
 }
diff --git a/multipathd/main.c b/multipathd/main.c
index fb520b64..269a96ec 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -936,7 +936,8 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map)
 	}
 	if (mpp && mpp->wait_for_udev &&
 	    (pathcount(mpp, PATH_UP) > 0 ||
-	     (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT &&
+	     (pathcount(mpp, PATH_GHOST) > 0 &&
+	      path_get_tpgs(pp) != TPGS_IMPLICIT &&
 	      mpp->ghost_delay_tick <= 0))) {
 		/* if wait_for_udev is set and valid paths exist */
 		condlog(3, "%s: delaying path addition until %s is fully initialized",
@@ -2106,8 +2107,8 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
 	 * paths if there are no other active paths in map.
 	 */
 	disable_reinstate = (newstate == PATH_GHOST &&
-			    pp->mpp->nr_active == 0 &&
-			    pp->tpgs == TPGS_IMPLICIT) ? 1 : 0;
+			     pp->mpp->nr_active == 0 &&
+			     path_get_tpgs(pp) == TPGS_IMPLICIT) ? 1 : 0;
 
 	pp->chkrstate = newstate;
 	if (newstate != pp->state) {
-- 
2.21.0




More information about the dm-devel mailing list