get_state() is now split into start_checker(), which runs the checker but doesn't wait for async checkers, and get_state(), which returns the state from the checker, after waiting for async checkers if necessary. Reviewed-by: Martin Wilck <mwilck@xxxxxxxx> Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> --- libmultipath/discovery.c | 22 ++++++++++++++++------ libmultipath/discovery.h | 4 +++- libmultipath/libmultipath.version | 1 + multipathd/main.c | 4 +++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 5648be60..e0f46ff2 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1974,30 +1974,29 @@ cciss_ioctl_pathinfo(struct path *pp) } int -get_state (struct path * pp, struct config *conf, int daemon, int oldstate) +start_checker (struct path * pp, struct config *conf, int daemon, int oldstate) { struct checker * c = &pp->checker; - int state; if (!checker_selected(c)) { if (daemon) { if (pathinfo(pp, conf, DI_SYSFS) != PATHINFO_OK) { condlog(3, "%s: couldn't get sysfs pathinfo", pp->dev); - return PATH_UNCHECKED; + return -1; } } select_detect_checker(conf, pp); select_checker(conf, pp); if (!checker_selected(c)) { condlog(3, "%s: No checker selected", pp->dev); - return PATH_UNCHECKED; + return -1; } checker_set_fd(c, pp->fd); if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) { checker_clear(c); condlog(3, "%s: checker init failed", pp->dev); - return PATH_UNCHECKED; + return -1; } } if (pp->mpp && !c->mpcontext) @@ -2008,6 +2007,15 @@ get_state (struct path * pp, struct config *conf, int daemon, int oldstate) else checker_set_sync(c); checker_check(c, oldstate); + return 0; +} + +int +get_state (struct path * pp) +{ + struct checker * c = &pp->checker; + int state; + state = checker_get_state(c); condlog(3, "%s: %s state = %s", pp->dev, checker_name(c), checker_state_name(state)); @@ -2455,7 +2463,9 @@ int pathinfo(struct path *pp, struct config *conf, int mask) if (mask & DI_CHECKER) { if (path_state == PATH_UP) { - int newstate = get_state(pp, conf, 0, path_state); + int newstate = PATH_UNCHECKED; + if (start_checker(pp, conf, 0, path_state) == 0) + newstate = get_state(pp); if (newstate != PATH_PENDING || pp->state == PATH_UNCHECKED || pp->state == PATH_WILD) diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h index c93abf1c..f3e0c618 100644 --- a/libmultipath/discovery.h +++ b/libmultipath/discovery.h @@ -34,7 +34,9 @@ int path_discovery (vector pathvec, int flag); int path_get_tpgs(struct path *pp); /* This function never returns TPGS_UNDEF */ int do_tur (char *); int path_offline (struct path *); -int get_state (struct path * pp, struct config * conf, int daemon, int state); +int start_checker(struct path * pp, struct config * conf, int daemon, + int state); +int get_state(struct path * pp); int get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen); int pathinfo (struct path * pp, struct config * conf, int mask); int alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice, diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version index 21d48da6..bb34d9e8 100644 --- a/libmultipath/libmultipath.version +++ b/libmultipath/libmultipath.version @@ -160,6 +160,7 @@ global: remove_wwid; replace_wwids; reset_checker_classes; + start_checker; select_all_tg_pt; select_action; select_find_multipaths_timeout; diff --git a/multipathd/main.c b/multipathd/main.c index 1b7fd04f..4f752adb 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -2324,7 +2324,9 @@ check_path_state(struct path *pp) if (newstate == PATH_UP) { conf = get_multipath_config(); pthread_cleanup_push(put_multipath_config, conf); - newstate = get_state(pp, conf, 1, newstate); + newstate = PATH_UNCHECKED; + if (start_checker(pp, conf, 1, newstate) == 0) + newstate = get_state(pp); pthread_cleanup_pop(1); } else { checker_clear_message(&pp->checker); -- 2.45.0