From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 11 May 2021 11:15:47 -0500 Subject: [PATCH] multipathd: don't fail to remove path once the map is removed 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 --- 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);