Blame SOURCES/0154-UPBZ-1291406-disable-reinstate.patch

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