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