In ev_remove_path(), if update_mpp_paths() fails, we delete the entire
map. However, since update_mpp_paths() happens before we call
set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so
remove_map_and_stop_waiter() doesn't remove the path when in removes the
map.  But with the map removed, there's nothing to keep us from removing
the path.

Call set_path_removed() before update_mpp_paths() to avoid the odd case
of ev_remove_path() removing the map but not the path.

Signed-off-by: Benjamin Marzinski <bmarz...@redhat.com>
Reviewed-by: Martin Wilck <mwi...@suse.com>
---
 libmultipath/structs_vec.c |  4 ++--
 multipathd/main.c          | 13 ++++++++-----
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
index d242c06b..75390198 100644
--- a/libmultipath/structs_vec.c
+++ b/libmultipath/structs_vec.c
@@ -45,8 +45,8 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec)
 
                                /*
                                 * Avoid adding removed paths to the map again
-                                * when we reload it. Such paths may exist if
-                                * domap fails in ev_remove_path().
+                                * when we reload it. Such paths may exist in
+                                * ev_remove_paths() or if it returns failure.
                                 */
                                pp1 = find_path_by_devt(pathvec, pp->dev_t);
                                if (pp1 && pp->initialized != INIT_REMOVED &&
diff --git a/multipathd/main.c b/multipathd/main.c
index 102946bf..449ce384 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1199,6 +1199,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, 
int need_do_map)
         * avoid referring to the map of an orphaned path
         */
        if ((mpp = pp->mpp)) {
+               /*
+                * Mark the path as removed. In case of success, we
+                * will delete it for good. Otherwise, it will be deleted
+                * later, unless all attempts to reload this map fail.
+                */
+               set_path_removed(pp);
+
                /*
                 * transform the mp->pg vector of vectors of paths
                 * into a mp->params string to feed the device-mapper
@@ -1210,13 +1217,9 @@ ev_remove_path (struct path *pp, struct vectors * vecs, 
int need_do_map)
                }
 
                /*
-                * Mark the path as removed. In case of success, we
-                * will delete it for good. Otherwise, it will be deleted
-                * later, unless all attempts to reload this map fail.
-                * Note: we have to explicitly remove pp from mpp->paths,
+                * we have to explicitly remove pp from mpp->paths,
                 * update_mpp_paths() doesn't do that.
                 */
-               set_path_removed(pp);
                i = find_slot(mpp->paths, pp);
                if (i != -1)
                        vector_del_slot(mpp->paths, i);
-- 
2.17.2

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to