From mboxrd@z Thu Jan 1 00:00:00 1970 From: Benjamin Marzinski Subject: [PATCH v2 08/12] libmutipath: continue to use old state on PATH_PENDING Date: Fri, 8 Mar 2019 17:12:01 -0600 Message-ID: <1552086725-18476-9-git-send-email-bmarzins@redhat.com> References: <1552086725-18476-1-git-send-email-bmarzins@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1552086725-18476-1-git-send-email-bmarzins@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com To: Christophe Varoqui Cc: device-mapper development , Martin Wilck List-Id: dm-devel.ids When pathinfo() sets pp->state to PATH_PENDING, it can cause problems with path checking. It should act more like check_path(). When check_path() sees a new state of PATH_PENDING, it doesn't update the path state at all, so a path's old state is normally never PATH_PENDING. As and example of the problems of setting a path to PATH_PENDING, If check_path() sets a path's state to PATH_UP, then a call to pathinfo() sets the state to PATH_PENDING, and then another call the check_path() sets the state to PATH_DOWN, multipathd won't fail the path in the kernel. Also, if a path's state is PATH_PENDING, and nr_active is recalculated, that path will count as down, even if the state was previously PATH_UP. If a path already has a state of PATH_WILD or PATH_UNCHECKED, changing it to PATH_PENDING won't hurt anything, and it will help anyone who sees it know what's actually happening. But otherwise, pathinfo() should leave the previous state alone. Reviewed-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- libmultipath/discovery.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index b08cb2d..28c00e5 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1946,8 +1946,11 @@ int pathinfo(struct path *pp, struct config *conf, int mask) if (mask & DI_CHECKER) { if (path_state == PATH_UP) { - pp->chkrstate = pp->state = get_state(pp, conf, 0, - path_state); + int newstate = get_state(pp, conf, 0, path_state); + if (newstate != PATH_PENDING || + pp->state == PATH_UNCHECKED || + pp->state == PATH_WILD) + pp->chkrstate = pp->state = newstate; if (pp->state == PATH_TIMEOUT) pp->state = PATH_DOWN; if (pp->state == PATH_UP && !pp->size) { -- 2.17.2