libmultipath: change failed path prio timeout
authorBenjamin Marzinski <bmarzins@redhat.com>
Wed, 19 Feb 2020 06:48:33 +0000 (00:48 -0600)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Mon, 2 Mar 2020 08:43:37 +0000 (09:43 +0100)
multipath will try to get the priority from a PATH_DOWN path, if the
path doesn't currently have a valid priority. However, if the priority
code needs to contact the device to get the priority, this is likely to
fail for PATH_DOWN paths.  This code dates back to when multipathd could
not easily reload device tables with failed paths, so getting the
correct priority was important to have a correctly configured device.
Now multipathd can simply reload the device to move the path to the
correct pathgroup when the path comes back up.  Since there are a number
of prioritizers that don't require talking to the device, multipath
shouldn't completely skip attempting to get the priority of these paths,
but it should set a small timeout, so that it isn't hanging in the
case where it needs to contact a device through a failed path.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/discovery.c
libmultipath/prio.c

index 47b12b6..6fa7fd7 100644 (file)
@@ -1717,11 +1717,10 @@ get_state (struct path * pp, struct config *conf, int daemon, int oldstate)
 }
 
 static int
-get_prio (struct path * pp)
+get_prio (struct path * pp, int timeout)
 {
        struct prio * p;
        struct config *conf;
-       int checker_timeout;
        int old_prio;
 
        if (!pp)
@@ -1740,11 +1739,8 @@ get_prio (struct path * pp)
                        return 1;
                }
        }
-       conf = get_multipath_config();
-       checker_timeout = conf->checker_timeout;
-       put_multipath_config(conf);
        old_prio = pp->priority;
-       pp->priority = prio_getprio(p, pp, checker_timeout);
+       pp->priority = prio_getprio(p, pp, timeout);
        if (pp->priority < 0) {
                /* this changes pp->offline, but why not */
                int state = path_offline(pp);
@@ -2151,11 +2147,13 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
 
         /*
          * Retrieve path priority, even for PATH_DOWN paths if it has never
-         * been successfully obtained before.
+         * been successfully obtained before. If path is down don't try
+         * for too long.
          */
        if ((mask & DI_PRIO) && path_state == PATH_UP && strlen(pp->wwid)) {
                if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
-                       get_prio(pp);
+                       get_prio(pp, (pp->state != PATH_DOWN)?
+                                    (conf->checker_timeout * 1000) : 10);
                }
        }
 
index 87de1f9..194563c 100644 (file)
 
 static LIST_HEAD(prioritizers);
 
-unsigned int get_prio_timeout(unsigned int checker_timeout,
+unsigned int get_prio_timeout(unsigned int timeout_ms,
                              unsigned int default_timeout)
 {
-       if (checker_timeout)
-               return checker_timeout * 1000;
+       if (timeout_ms)
+               return timeout_ms;
        return default_timeout;
 }