--- 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 #include #include +#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 {