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

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