Multipath again waits for running checkers to complete. In pathinfo(),
mutipath will just wait 1ms if the checker is running. In checkerloop(),
if there are running checkers, multipathd will drop the vecs lock and
wait for 5ms. The difference it wait times is because multipathd cannot
drop the vecs lock in pathinfo.

Signed-off-by: Benjamin Marzinski <bmarz...@redhat.com>
---
 libmultipath/discovery.c          |  9 ++++++++-
 libmultipath/libmultipath.version |  1 +
 multipathd/main.c                 | 12 +++++++++++-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 6ccdfa0b..1d48c30a 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -2467,8 +2467,15 @@ int pathinfo(struct path *pp, struct config *conf, int 
mask)
        if (mask & DI_CHECKER) {
                if (path_state == PATH_UP) {
                        int newstate = PATH_UNCHECKED;
-                       if (start_checker(pp, conf, 0, path_state) == 0)
+                       if (start_checker(pp, conf, 0, path_state) == 0) {
+                               if (checker_need_wait(&pp->checker)) {
+                                       struct timespec wait = {
+                                               .tv_nsec = 1000 * 1000,
+                                       };
+                                       nanosleep(&wait, NULL);
+                               }
                                newstate = get_state(pp);
+                       }
                        if (newstate != PATH_PENDING ||
                            pp->state == PATH_UNCHECKED ||
                            pp->state == PATH_WILD)
diff --git a/libmultipath/libmultipath.version 
b/libmultipath/libmultipath.version
index 6439d3a7..c2e5f552 100644
--- a/libmultipath/libmultipath.version
+++ b/libmultipath/libmultipath.version
@@ -62,6 +62,7 @@ global:
        checker_enable;
        checker_message;
        checker_name;
+       checker_need_wait;
        checker_state_name;
        check_foreign;
        cleanup_bindings;
diff --git a/multipathd/main.c b/multipathd/main.c
index 5e68e470..5bac76ae 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -2848,6 +2848,7 @@ update_uninitialized_path(struct vectors * vecs, struct 
path * pp)
 enum checker_state {
        CHECKER_STARTING,
        CHECKER_CHECKING_PATHS,
+       CHECKER_WAITING_FOR_PATHS,
        CHECKER_UPDATING_PATHS,
        CHECKER_FINISHED,
 };
@@ -2859,6 +2860,7 @@ check_paths(struct vectors *vecs, unsigned int ticks)
        struct timespec diff_time, start_time, end_time;
        struct path *pp;
        int i;
+       bool need_wait = false;
 
        get_monotonic_time(&start_time);
 
@@ -2869,6 +2871,9 @@ check_paths(struct vectors *vecs, unsigned int ticks)
                        pp->is_checked = check_path(pp, ticks);
                else
                        pp->is_checked = check_uninitialized_path(pp, ticks);
+               if (pp->is_checked == CHECK_PATH_STARTED &&
+                   checker_need_wait(&pp->checker))
+                       need_wait = true;
                if (++paths_checked % 128 == 0 &&
                    (lock_has_waiters(&vecs->lock) || waiting_clients())) {
                        get_monotonic_time(&end_time);
@@ -2877,7 +2882,7 @@ check_paths(struct vectors *vecs, unsigned int ticks)
                                return CHECKER_CHECKING_PATHS;
                }
        }
-       return CHECKER_UPDATING_PATHS;
+       return need_wait ? CHECKER_WAITING_FOR_PATHS : CHECKER_UPDATING_PATHS;
 }
 
 static enum checker_state
@@ -2999,6 +3004,11 @@ checkerloop (void *ap)
                        if (checker_state != CHECKER_FINISHED) {
                                /* Yield to waiters */
                                struct timespec wait = { .tv_nsec = 10000, };
+                               if (checker_state == CHECKER_WAITING_FOR_PATHS) 
{
+                                       /* wait 5ms */
+                                       wait.tv_nsec = 5 * 1000 * 1000;
+                                       checker_state = CHECKER_UPDATING_PATHS;
+                               }
                                nanosleep(&wait, NULL);
                        }
                }
-- 
2.45.0


Reply via email to