libmultipath: get_prio(): don't reset prio for inaccessible paths master
authorMartin Wilck <mwilck@suse.com>
Thu, 11 Apr 2019 10:49:23 +0000 (12:49 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Fri, 19 Apr 2019 13:37:43 +0000 (15:37 +0200)
pathinfo() doesn't call get_prio() if a path is down, now keeping the old
priority value. But if a path becomes inaccessible between the state check
and the get_prio() call, retrieving the priority will likely fail, and the
path priority will be reset to PRIO_UNDEF. This makes it timing-dependent
how the priority of a failed path is treated. Fix that by checking the path
state in get_prio() if an error occurs, and not touching pp->priority if
the path is in inaccessible state. A checker_check() call would be too
much here, but a quick path_offline() check seems appropriate.

Keep the previous behavior for the case where getting the priority fails
although the path is apparently healthy. This is presumably a very rare
condition, in which it seems actually wrong to preserve the old prio value.

Signed-off-by: Martin Wilck <mwilck@suse.com>
libmultipath/discovery.c

index 5c3b81f..b3dc60b 100644 (file)
@@ -1645,8 +1645,17 @@ get_prio (struct path * pp)
        old_prio = pp->priority;
        pp->priority = prio_getprio(p, pp, checker_timeout);
        if (pp->priority < 0) {
-               condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
-               pp->priority = PRIO_UNDEF;
+               /* this changes pp->offline, but why not */
+               int state = path_offline(pp);
+
+               if (state == PATH_DOWN || state == PATH_PENDING)
+                       condlog(3, "%s: %s prio error in state %d, keeping prio = %d",
+                               pp->dev, prio_name(p), state, pp->priority);
+               else {
+                       condlog(3, "%s: %s prio error in state %d",
+                               pp->dev, prio_name(p), state);
+                       pp->priority = PRIO_UNDEF;
+               }
                return 1;
        }
        condlog((old_prio == pp->priority ? 4 : 3), "%s: %s prio = %u",