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

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