---
libmultipath/discovery.c | 10 ++++++--
libmultipath/structs.h | 1
libmultipath/structs_vec.c | 4 ++-
multipathd/main.c | 52 ++++++++++++++++++++++++++++++++-------------
4 files changed, 49 insertions(+), 18 deletions(-)
Index: multipath-tools-130222/libmultipath/discovery.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/discovery.c
+++ multipath-tools-130222/libmultipath/discovery.c
@@ -1425,10 +1425,13 @@ pathinfo (struct path *pp, vector hwtabl
pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
if (pp->fd < 0) {
+ pp->missing_udev_info = INFO_REINIT;
condlog(4, "Couldn't open node for %s: %s",
pp->dev, strerror(errno));
goto blank;
}
+ if (pp->missing_udev_info == INFO_REINIT)
+ pp->missing_udev_info = INFO_OK;
if (mask & DI_SERIAL)
get_geometry(pp);
@@ -1443,8 +1446,11 @@ pathinfo (struct path *pp, vector hwtabl
if (mask & DI_CHECKER) {
if (path_state == PATH_UP) {
- pp->chkrstate = pp->state = get_state(pp, 0,
- path_state);
+ int newstate = get_state(pp, 0, path_state);
+ if (newstate != PATH_PENDING ||
+ pp->state == PATH_UNCHECKED ||
+ pp->state == PATH_WILD)
+ pp->chkrstate = pp->state = newstate;
if (pp->state == PATH_UNCHECKED ||
pp->state == PATH_WILD)
goto blank;
Index: multipath-tools-130222/libmultipath/structs.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/structs.h
+++ multipath-tools-130222/libmultipath/structs.h
@@ -184,6 +184,7 @@ enum marginal_path_states {
enum missing_udev_info_states {
INFO_OK,
+ INFO_REINIT,
INFO_MISSING,
INFO_REQUESTED,
};
Index: multipath-tools-130222/multipathd/main.c
===================================================================
--- multipath-tools-130222.orig/multipathd/main.c
+++ multipath-tools-130222/multipathd/main.c
@@ -1381,7 +1381,7 @@ int update_path_groups(struct multipath
return 0;
}
-void
+int
check_path (struct vectors * vecs, struct path * pp)
{
int newstate;
@@ -1390,19 +1390,20 @@ check_path (struct vectors * vecs, struc
int disable_reinstate = 0;
int oldchkrstate = pp->chkrstate;
- if (!pp->mpp && (pp->missing_udev_info != INFO_MISSING ||
- pp->retriggers >= conf->retrigger_tries))
- return;
+ if (!pp->mpp && pp->missing_udev_info != INFO_REINIT &&
+ (pp->missing_udev_info != INFO_MISSING ||
+ pp->retriggers >= conf->retrigger_tries))
+ return 0;
if (pp->tick && --pp->tick)
- return; /* don't check this path yet */
+ return 0; /* don't check this path yet */
- if (!pp->mpp) {
+ if (!pp->mpp && pp->missing_udev_info == INFO_MISSING) {
pp->missing_udev_info = INFO_REQUESTED;
pp->retriggers++;
sysfs_attr_set_value(pp->udev, "uevent", "change",
strlen("change"));
- return;
+ return 0;
}
/*
@@ -1412,6 +1413,21 @@ check_path (struct vectors * vecs, struc
pp->tick = conf->checkint;
newstate = path_offline(pp);
+ if (!pp->mpp) {
+ if (newstate == PATH_UP &&
+ pp->missing_udev_info == INFO_REINIT) {
+ int ret;
+ condlog(3, "%s: add missing path", pp->dev);
+ ret = pathinfo(pp, conf->hwtable,
+ DI_ALL | DI_BLACKLIST);
+ if (ret == PATHINFO_OK && strlen(pp->wwid)) {
+ ev_add_path(pp, vecs);
+ pp->tick = 1;
+ } else if (ret == PATHINFO_SKIPPED)
+ return -1;
+ }
+ return 0;
+ }
if (newstate == PATH_UP)
newstate = get_state(pp, 1, newstate);
else
@@ -1426,7 +1442,7 @@ check_path (struct vectors * vecs, struc
if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
condlog(2, "%s: unusable path", pp->dev);
pathinfo(pp, conf->hwtable, 0);
- return;
+ return 0;
}
/*
* Async IO in flight. Keep the previous path state
@@ -1434,7 +1450,7 @@ check_path (struct vectors * vecs, struc
*/
if (newstate == PATH_PENDING) {
pp->tick = 1;
- return;
+ return 0;
}
/*
* Synchronize with kernel state
@@ -1446,7 +1462,7 @@ check_path (struct vectors * vecs, struc
}
/* if update_multipath_strings orphaned the path, quit early */
if (!pp->mpp)
- return;
+ return 0;
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
pp->io_err_disable_reinstate && need_io_err_check(pp)) {
@@ -1456,7 +1472,7 @@ check_path (struct vectors * vecs, struc
* be recoverd in time
*/
pp->tick = 1;
- return;
+ return 0;
}
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
@@ -1464,7 +1480,7 @@ check_path (struct vectors * vecs, struc
if (pp->mpp && pp->mpp->nr_active > 0) {
pp->state = PATH_DELAYED;
pp->wait_checks--;
- return;
+ return 0;
} else
pp->wait_checks = 0;
}
@@ -1512,7 +1528,7 @@ check_path (struct vectors * vecs, struc
pp->mpp->failback_tick = 0;
pp->mpp->stat_path_failures++;
- return;
+ return 0;
}
if(newstate == PATH_UP || newstate == PATH_GHOST){
@@ -1594,7 +1610,7 @@ check_path (struct vectors * vecs, struc
if (pp->mpp->wait_for_udev)
- return;
+ return 0;
/*
* path prio refreshing
*/
@@ -1613,6 +1629,7 @@ check_path (struct vectors * vecs, struc
(chkr_new_path_up && followover_should_failback(pp)))
switch_pathgroup(pp->mpp);
}
+ return 0;
}
static void *
@@ -1642,7 +1659,12 @@ checkerloop (void *ap)
if (vecs->pathvec) {
vector_foreach_slot (vecs->pathvec, pp, i) {
- check_path(vecs, pp);
+ int rc = check_path(vecs, pp);
+ if (rc < 0) {
+ vector_del_slot(vecs->pathvec, i);
+ free_path(pp);
+ i--;
+ }
}
}
if (vecs->mpvec) {
Index: multipath-tools-130222/libmultipath/structs_vec.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/structs_vec.c
+++ multipath-tools-130222/libmultipath/structs_vec.c
@@ -274,9 +274,11 @@ void sync_paths(struct multipath *mpp, v
}
}
if (!found) {
- condlog(3, "%s dropped path %s", mpp->alias, pp->dev);
+ condlog(2, "%s dropped path %s", mpp->alias, pp->dev);
vector_del_slot(mpp->paths, i--);
orphan_path(pp);
+ memset(pp->wwid, 0, WWID_SIZE);
+ pp->missing_udev_info = INFO_REINIT;
}
}
update_mpp_paths(mpp, pathvec);