From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Wed, 17 Mar 2021 17:18:22 +0100 Subject: [PATCH] libmultipath: merge update_multipath_table() and update_multipath_status() Since 378cb66 ("multipath: use update_pathvec_from_dm()"), we remove paths and even pathgroups from multipathd's data structures in update_multipath_table() if these paths are found to be non-existent. But update_multipath_status() is called afterwards, and it uses the kernel's mapping of pathgroups and paths, which won't match any more if any members had been removed. disassemble_status() returns an error if the number of path groups doesn't match, causing the entire structure setup to fail. And because disassemble_status() doesn't check the dev_t against the corresponding values in multipathd's data structures, it may assign wrong DM state to paths. Fix this by calling disassemble_status() before making any changes to the data structure in update_pathvec_from_dm(). This can be easily done, because every call to update_multipath_status() is preceded by a call to update_multipath_table() anyway, and vice versa. So we simply merge the two functions into one. This actually simplifies the code for all callers. As we remove a symbol, the major library version must be bumped. Fixes: 378cb66 ("multipath: use update_pathvec_from_dm()") Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- libmpathpersist/mpath_persist.c | 1 - libmultipath/libmultipath.version | 30 ++++++++---------------- libmultipath/structs_vec.c | 38 ++++++++----------------------- multipath/main.c | 6 ++--- multipathd/main.c | 5 +--- 5 files changed, 21 insertions(+), 59 deletions(-) diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c index 5c95af20..190e9707 100644 --- a/libmpathpersist/mpath_persist.c +++ b/libmpathpersist/mpath_persist.c @@ -408,7 +408,6 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid) continue; if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || - update_multipath_status(mpp) != DMP_OK || update_mpp_paths(mpp, pathvec)) { condlog(1, "error parsing map %s", mpp->wwid); remove_map(mpp, pathvec, curmp, PURGE_VEC); diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version index e9b4608f..0cff3111 100644 --- a/libmultipath/libmultipath.version +++ b/libmultipath/libmultipath.version @@ -31,7 +31,7 @@ * The new version inherits the previous ones. */ -LIBMULTIPATH_4.0.0 { +LIBMULTIPATH_5.0.0 { global: /* symbols referenced by multipath and multipathd */ add_foreign; @@ -198,7 +198,6 @@ global: uevent_is_mpath; uevent_listen; update_mpp_paths; - update_multipath_status; update_multipath_strings; update_multipath_table; update_pathvec_from_dm; @@ -256,33 +255,22 @@ global: libmultipath_init; libmultipath_exit; -local: - *; -}; - -LIBMULTIPATH_4.1.0 { -global: + /* added in 4.1.0 */ libmp_verbosity; -} LIBMULTIPATH_4.0.0; -LIBMULTIPATH_4.2.0 { -global: + /* added in 4.2.0 */ dm_prereq; skip_libmp_dm_init; -} LIBMULTIPATH_4.1.0; -LIBMULTIPATH_4.3.0 { -global: + /* added in 4.3.0 */ start_checker_thread; -} LIBMULTIPATH_4.2.0; -LIBMULTIPATH_4.4.0 { -global: + /* added in 4.4.0 */ get_next_string; -} LIBMULTIPATH_4.3.0; -LIBMULITIPATH_4.5.0 { -global: + /* added in 4.5.0 */ get_vpd_sgio; trigger_partitions_udev_change; -} LIBMULTIPATH_4.4.0; +local: + *; +}; diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index 47b1d03e..d242c06b 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -423,44 +423,27 @@ update_multipath_table (struct multipath *mpp, vector pathvec, int flags) r = dm_get_map(mpp->alias, &mpp->size, params); if (r != DMP_OK) { - condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); + condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); return r; } if (disassemble_map(pathvec, params, mpp)) { - condlog(3, "%s: cannot disassemble map", mpp->alias); + condlog(2, "%s: cannot disassemble map", mpp->alias); return DMP_ERR; } + *params = '\0'; + if (dm_get_status(mpp->alias, params) != DMP_OK) + condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); + else if (disassemble_status(params, mpp)) + condlog(2, "%s: cannot disassemble status", mpp->alias); + /* FIXME: we should deal with the return value here */ update_pathvec_from_dm(pathvec, mpp, flags); return DMP_OK; } -int -update_multipath_status (struct multipath *mpp) -{ - int r = DMP_ERR; - char status[PARAMS_SIZE] = {0}; - - if (!mpp) - return r; - - r = dm_get_status(mpp->alias, status); - if (r != DMP_OK) { - condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); - return r; - } - - if (disassemble_status(status, mpp)) { - condlog(3, "%s: cannot disassemble status", mpp->alias); - return DMP_ERR; - } - - return DMP_OK; -} - static struct path *find_devt_in_pathgroups(const struct multipath *mpp, const char *dev_t) { @@ -538,11 +521,8 @@ update_multipath_strings(struct multipath *mpp, vector pathvec) r = update_multipath_table(mpp, pathvec, 0); if (r != DMP_OK) return r; - sync_paths(mpp, pathvec); - r = update_multipath_status(mpp); - if (r != DMP_OK) - return r; + sync_paths(mpp, pathvec); vector_foreach_slot(mpp->pg, pgp, i) if (pgp->paths) diff --git a/multipath/main.c b/multipath/main.c index 3f97582b..ef89c7cf 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -196,8 +196,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) continue; } - if (update_multipath_table(mpp, pathvec, flags) != DMP_OK || - update_multipath_status(mpp) != DMP_OK) { + if (update_multipath_table(mpp, pathvec, flags) != DMP_OK) { condlog(1, "error parsing map %s", mpp->wwid); remove_map(mpp, pathvec, curmp, PURGE_VEC); i--; @@ -263,8 +262,7 @@ static int check_usable_paths(struct config *conf, if (mpp == NULL) goto free; - if (update_multipath_table(mpp, pathvec, 0) != DMP_OK || - update_multipath_status(mpp) != DMP_OK) + if (update_multipath_table(mpp, pathvec, 0) != DMP_OK) goto free; vector_foreach_slot (mpp->pg, pg, i) { diff --git a/multipathd/main.c b/multipathd/main.c index e0797ccd..154a4eef 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -559,8 +559,6 @@ add_map_without_path (struct vectors *vecs, const char *alias) if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) goto out; - if (update_multipath_status(mpp) != DMP_OK) - goto out; if (!vector_alloc_slot(vecs->mpvec)) goto out; @@ -1469,8 +1467,7 @@ map_discovery (struct vectors * vecs) return 1; vector_foreach_slot (vecs->mpvec, mpp, i) - if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK || - update_multipath_status(mpp) != DMP_OK) { + if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { remove_map(mpp, vecs->pathvec, vecs->mpvec, PURGE_VEC); i--; }