Modifying the pathvec in a deep call stack is unexpected and error-prone. Free paths in the checkerloop instead, after having synced all maps.
Suggested-by: Benjamin Marzinski <[email protected]> Signed-off-by: Martin Wilck <[email protected]> --- libmultipath/libmultipath.version | 1 + libmultipath/structs_vec.c | 7 +++---- libmultipath/structs_vec.h | 1 + multipathd/main.c | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version index 89ae2a3..e5b7b83 100644 --- a/libmultipath/libmultipath.version +++ b/libmultipath/libmultipath.version @@ -58,6 +58,7 @@ global: change_foreign; check_alias_settings; check_daemon; + check_removed_paths; checker_clear_message; checker_disable; checker_enable; diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index f651b29..3a9ab58 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -573,16 +573,16 @@ static struct path *find_devt_in_pathgroups(const struct multipath *mpp, return NULL; } -static void check_removed_paths(const struct multipath *mpp, vector pathvec) +void check_removed_paths(vector pathvec) { struct path *pp; int i; vector_foreach_slot(pathvec, pp, i) { - if (pp->mpp == mpp && + if (pp->mpp && (pp->initialized == INIT_REMOVED || pp->initialized == INIT_PARTIAL) && - !find_devt_in_pathgroups(mpp, pp->dev_t)) { + !find_devt_in_pathgroups(pp->mpp, pp->dev_t)) { condlog(2, "%s: %s: freeing path in %s state", __func__, pp->dev, pp->initialized == INIT_REMOVED ? @@ -615,7 +615,6 @@ void sync_paths(struct multipath *mpp, vector pathvec) orphan_path(pp, "path removed externally"); } } - check_removed_paths(mpp, pathvec); update_mpp_paths(mpp, pathvec); vector_foreach_slot (mpp->paths, pp, i) pp->mpp = mpp; diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h index 1188ada..cb02d75 100644 --- a/libmultipath/structs_vec.h +++ b/libmultipath/structs_vec.h @@ -18,6 +18,7 @@ int adopt_paths (vector pathvec, struct multipath *mpp, void orphan_path (struct path * pp, const char *reason); void set_path_removed(struct path *pp); +void check_removed_paths(vector pathvec); int verify_paths(struct multipath *mpp); int update_mpp_paths(struct multipath * mpp, vector pathvec); int update_multipath_strings (struct multipath *mpp, vector pathvec); diff --git a/multipathd/main.c b/multipathd/main.c index d3bf4d0..49a1f25 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -3127,6 +3127,7 @@ static void checker_finished(struct vectors *vecs, unsigned int ticks) } if (uev_timed_out && !need_to_delay_reconfig(vecs)) unblock_reconfigure(); + check_removed_paths(vecs->pathvec); partial_retrigger_tick(vecs->pathvec); } -- 2.52.0
