@@ -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)
@@ -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,
@@ -160,6 +160,7 @@ global:
remove_wwid;
replace_wwids;
reset_checker_classes;
+ start_checker;
select_all_tg_pt;
select_action;
select_find_multipaths_timeout;
@@ -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);
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. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> --- libmultipath/discovery.c | 22 ++++++++++++++++------ libmultipath/discovery.h | 4 +++- libmultipath/libmultipath.version | 1 + multipathd/main.c | 4 +++- 4 files changed, 23 insertions(+), 8 deletions(-)