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.
215 lines
6.1 KiB
215 lines
6.1 KiB
--- |
|
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);
|
|
|