@@ -146,6 +146,7 @@ uninitialize_path(struct path *pp)
return;
pp->dmstate = PSTATE_UNDEF;
+ pp->state = PATH_UNCHECKED;
pp->uid_attribute = NULL;
pp->checker_timeout = 0;
@@ -723,7 +723,8 @@ sync_map_state(struct multipath *mpp)
vector_foreach_slot (mpp->pg, pgp, i){
vector_foreach_slot (pgp->paths, pp, j){
- if (pp->state == PATH_UNCHECKED ||
+ if (pp->initialized == INIT_REMOVED ||
+ pp->state == PATH_UNCHECKED ||
pp->state == PATH_WILD ||
pp->state == PATH_DELAYED)
continue;
@@ -540,7 +540,11 @@ add_partial_path(struct path *pp, struct vectors *vecs)
if (strlen(wwid) && strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
condlog(0, "%s: path wwid changed from '%s' to '%s'. removing",
pp->dev, wwid, pp->wwid);
- ev_remove_path(pp, vecs, 1);
+ if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) &&
+ pp->mpp) {
+ pp->dmstate = PSTATE_FAILED;
+ dm_fail_path(pp->mpp->alias, pp->dev_t);
+ }
udev_device_unref(udd);
return -1;
}
If multipathd noticed that the WWID didn't match the device when adding a partial path, but removing it failed, multipathd wasn't disabling the path. Instead of calling handle_path_wwid_change(), which doesn't make much sense when multipathd is expecting a uevent, just manually disable the path if ev_remove_path() fails. Since the path hasn't actually been removed, multipathd needs to make sure that it says failed when the path state is resynced with the kernel. Set the state to PATH_UNCHECKED in orphan_path(), and additionally skip all path in INIT_REMOVED in sync_map_state(). Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> --- libmultipath/structs.c | 1 + libmultipath/structs_vec.c | 3 ++- multipathd/cli_handlers.c | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-)