[PATCH 1/3] libmultipath: return 'pending' state when port is in transition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux