Blame SOURCES/0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch

a1c519
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
a1c519
From: Benjamin Marzinski <bmarzins@redhat.com>
a1c519
Date: Thu, 21 Feb 2019 13:05:43 -0600
a1c519
Subject: [PATCH] libmutipath: continue to use old state on PATH_PENDING
a1c519
a1c519
When pathinfo() sets pp->state to PATH_PENDING, it can cause problems
a1c519
with path checking.  It should act more like check_path(). When
a1c519
check_path() sees a new state of PATH_PENDING, it doesn't update the
a1c519
path state at all, so a path's old state is normally never PATH_PENDING.
a1c519
a1c519
As and example of the problems of setting a path to PATH_PENDING, If
a1c519
check_path() sets a path's state to PATH_UP, then a call to pathinfo()
a1c519
sets the state to PATH_PENDING, and then another call the check_path()
a1c519
sets the state to PATH_DOWN, multipathd won't fail the path in the
a1c519
kernel. Also, if a path's state is PATH_PENDING, and nr_active is
a1c519
recalculated, that path will count as down, even if the state was
a1c519
previously PATH_UP. If a path already has a state of PATH_WILD or
a1c519
PATH_UNCHECKED, changing it to PATH_PENDING won't hurt anything, and it
a1c519
will help anyone who sees it know what's actually happening. But
a1c519
otherwise, pathinfo() should leave the previous state alone.
a1c519
a1c519
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
a1c519
---
a1c519
 libmultipath/discovery.c | 7 +++++--
a1c519
 1 file changed, 5 insertions(+), 2 deletions(-)
a1c519
a1c519
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
a1c519
index b08cb2d..28c00e5 100644
a1c519
--- a/libmultipath/discovery.c
a1c519
+++ b/libmultipath/discovery.c
a1c519
@@ -1946,8 +1946,11 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
a1c519
 
a1c519
 	if (mask & DI_CHECKER) {
a1c519
 		if (path_state == PATH_UP) {
a1c519
-			pp->chkrstate = pp->state = get_state(pp, conf, 0,
a1c519
-							      path_state);
a1c519
+			int newstate = get_state(pp, conf, 0, path_state);
a1c519
+			if (newstate != PATH_PENDING ||
a1c519
+			    pp->state == PATH_UNCHECKED ||
a1c519
+			    pp->state == PATH_WILD)
a1c519
+				pp->chkrstate = pp->state = newstate;
a1c519
 			if (pp->state == PATH_TIMEOUT)
a1c519
 				pp->state = PATH_DOWN;
a1c519
 			if (pp->state == PATH_UP && !pp->size) {
a1c519
-- 
a1c519
2.17.2
a1c519