The tur checker should not return that a path is down when it is in the transitioning state. Instead, it should return PATH_PENDING, so that the path retains its current state, and multipathd can react quickly when it moves out of the transitioning state. The code needs to be careful to differentiate between when the checker thread has finished and returned PATH_PENDING, and when it is still running. Reported-by: Brian Bunker <brian@xxxxxxxxxxxxxxx> Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> --- libmultipath/checkers/tur.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c index 551dc4f0..a5045f10 100644 --- a/libmultipath/checkers/tur.c +++ b/libmultipath/checkers/tur.c @@ -32,6 +32,7 @@ enum { MSG_TUR_RUNNING = CHECKER_FIRST_MSGID, MSG_TUR_TIMEOUT, MSG_TUR_FAILED, + MSG_TUR_TRANSITIONING, }; #define _IDX(x) (MSG_ ## x - CHECKER_FIRST_MSGID) @@ -39,6 +40,7 @@ const char *libcheck_msgtable[] = { [_IDX(TUR_RUNNING)] = " still running", [_IDX(TUR_TIMEOUT)] = " timed out", [_IDX(TUR_FAILED)] = " failed to initialize", + [_IDX(TUR_TRANSITIONING)] = " reports path is transitioning", NULL, }; @@ -186,6 +188,13 @@ retry: */ *msgid = CHECKER_MSGID_GHOST; return PATH_GHOST; + } else if (asc == 0x04 && ascq == 0x0a) { + /* + * LOGICAL UNIT NOT ACCESSIBLE, + * ASYMMETRIC ACCESS STATE TRANSITION + */ + *msgid = MSG_TUR_TRANSITIONING; + return PATH_PENDING; } } *msgid = CHECKER_MSGID_DOWN; @@ -350,6 +359,7 @@ int libcheck_check(struct checker * c) condlog(3, "%d:%d : tur checker not finished", major(ct->devt), minor(ct->devt)); tur_status = PATH_PENDING; + c->msgid = MSG_TUR_RUNNING; } else { /* TUR checker done */ ct->thread = 0; @@ -404,7 +414,7 @@ int libcheck_check(struct checker * c) /* Start new TUR checker */ pthread_mutex_lock(&ct->lock); tur_status = ct->state = PATH_PENDING; - ct->msgid = CHECKER_MSGID_NONE; + c->msgid = ct->msgid = MSG_TUR_RUNNING; pthread_mutex_unlock(&ct->lock); ct->fd = c->fd; ct->timeout = c->timeout; @@ -424,7 +434,7 @@ int libcheck_check(struct checker * c) } tur_timeout(&tsp); pthread_mutex_lock(&ct->lock); - if (ct->state == PATH_PENDING) + if (ct->state == PATH_PENDING && ct->msgid == MSG_TUR_RUNNING) r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp); if (!r) { @@ -432,7 +442,7 @@ int libcheck_check(struct checker * c) c->msgid = ct->msgid; } pthread_mutex_unlock(&ct->lock); - if (tur_status == PATH_PENDING) { + if (tur_status == PATH_PENDING && c->msgid == MSG_TUR_RUNNING) { condlog(4, "%d:%d : tur checker still running", major(ct->devt), minor(ct->devt)); } else { -- 2.17.2 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/dm-devel