|
|
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 |
|