You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
6.1 KiB
216 lines
6.1 KiB
4 years ago
|
---
|
||
|
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);
|