Blob Blame History Raw
---
 libmultipath/propsel.c |   20 ++++++++++++++++----
 libmultipath/structs.h |    1 +
 multipathd/main.c      |   37 ++++++++++++++++++++++++++-----------
 3 files changed, 43 insertions(+), 15 deletions(-)

Index: multipath-tools-130222/libmultipath/propsel.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/propsel.c
+++ multipath-tools-130222/libmultipath/propsel.c
@@ -398,9 +398,11 @@ detect_prio(struct path * pp)
 {
 	int ret;
 	struct prio *p = &pp->prio;
+	int tpgs = 0;
 
-	if (get_target_port_group_support(pp->fd) <= 0)
+	if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
 		return;
+	pp->tpgs = tpgs;
 	ret = get_target_port_group(pp->fd, NULL);
 	if (ret < 0)
 		return;
@@ -432,7 +434,7 @@ select_prio (struct path * pp)
 			pp->dev, prio_name(p));
 		condlog(3, "%s: prio args = %s (LUN setting)",
 			pp->dev, prio_args(p));
-		return 0;
+		goto out;
 	}
 
 	if (pp->hwe && pp->hwe->prio_name) {
@@ -441,7 +443,7 @@ select_prio (struct path * pp)
 			pp->dev, pp->hwe->prio_name);
 		condlog(3, "%s: prio args = %s (controller setting)",
 			pp->dev, pp->hwe->prio_args);
-		return 0;
+		goto out;
 	}
 	if (conf->prio_name) {
 		prio_get(p, conf->prio_name, conf->prio_args);
@@ -449,13 +451,23 @@ select_prio (struct path * pp)
 			pp->dev, conf->prio_name);
 		condlog(3, "%s: prio args = %s (config file default)",
 			pp->dev, conf->prio_args);
-		return 0;
+		goto out;
 	}
 	prio_get(p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
 	condlog(3, "%s: prio = %s (internal default)",
 		pp->dev, DEFAULT_PRIO);
 	condlog(3, "%s: prio args = %s (internal default)",
 		pp->dev, DEFAULT_PRIO_ARGS);
+out:
+	/*
+ 	 * fetch tpgs mode for alua
+ 	 */
+	if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
+		int tpgs = 0;
+		if (!pp->tpgs &&
+		    (tpgs = get_target_port_group_support(pp->fd)) >= 0)
+			pp->tpgs = tpgs;
+	}
 	return 0;
 }
 
Index: multipath-tools-130222/libmultipath/structs.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/structs.h
+++ multipath-tools-130222/libmultipath/structs.h
@@ -193,6 +193,7 @@ struct path {
 	int detect_prio;
 	int watch_checks;
 	int wait_checks;
+	int tpgs;
 	char * uid_attribute;
 	struct prio prio;
 	char * prio_args;
Index: multipath-tools-130222/multipathd/main.c
===================================================================
--- multipath-tools-130222.orig/multipathd/main.c
+++ multipath-tools-130222/multipathd/main.c
@@ -19,6 +19,7 @@
 #include <libudev.h>
 #include <semaphore.h>
 #include <mpath_persist.h>
+#include "prioritizers/alua_rtpg.h"
 
 /*
  * libcheckers
@@ -1248,6 +1249,7 @@ check_path (struct vectors * vecs, struc
 	int newstate;
 	int new_path_up = 0;
 	int chkr_new_path_up = 0;
+	int disable_reinstate = 0;
 	int oldchkrstate = pp->chkrstate;
 
 	if (!pp->mpp && (pp->missing_udev_info != INFO_MISSING ||
@@ -1312,6 +1314,16 @@ check_path (struct vectors * vecs, struc
 			pp->wait_checks = 0;
 	}
 
+	/*
+	 * don't reinstate failed path, if its in stand-by
+	 * and if target supports only implicit tpgs mode.
+	 * this will prevent unnecessary i/o by dm on stand-by
+	 * 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->chkrstate = newstate;
 	if (newstate != pp->state) {
 		int oldstate = pp->state;
@@ -1367,15 +1379,17 @@ check_path (struct vectors * vecs, struc
 		/*
 		 * reinstate this path
 		 */
-		if (oldstate != PATH_UP &&
-		    oldstate != PATH_GHOST) {
-			if (pp->mpp->delay_watch_checks > 0)
-				pp->watch_checks = pp->mpp->delay_watch_checks;
-			reinstate_path(pp, 1);
-		} else {
-			if (pp->watch_checks > 0)
-				pp->watch_checks--;
-			reinstate_path(pp, 0);
+		if (!disable_reinstate) {
+			if (oldstate != PATH_UP &&
+			    oldstate != PATH_GHOST) {
+				if (pp->mpp->delay_watch_checks > 0)
+					pp->watch_checks = pp->mpp->delay_watch_checks;
+				reinstate_path(pp, 1);
+			} else {
+				if (pp->watch_checks > 0)
+					pp->watch_checks--;
+				reinstate_path(pp, 0);
+			}
 		}
 		new_path_up = 1;
 
@@ -1390,8 +1404,9 @@ check_path (struct vectors * vecs, struc
 			enable_group(pp);
 	}
 	else if (newstate == PATH_UP || newstate == PATH_GHOST) {
-		if (pp->dmstate == PSTATE_FAILED ||
-		    pp->dmstate == PSTATE_UNDEF) {
+		if ((pp->dmstate == PSTATE_FAILED ||
+		    pp->dmstate == PSTATE_UNDEF) &&
+		    !disable_reinstate) {
 			/* Clear IO errors */
 			reinstate_path(pp, 0);
 		} else {