[dm-devel] [PATCH v2 1/3] libmultipath: merge update_multipath_table() and update_multipath_status()
Benjamin Marzinski
bmarzins at redhat.com
Thu Mar 18 14:47:46 UTC 2021
On Thu, Mar 18, 2021 at 10:14:11AM +0100, mwilck at suse.com wrote:
> From: Martin Wilck <mwilck at suse.com>
>
> 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.
>
Reviewed-by: Benjamin Marzinski <bmarzins at redhat.com>
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
> Changes v1 -> v2:
> - log errors at -v2 in update_multipath_table() (Ben)
> - return error in update_multipath_strings() if
> update_multipath_table() fails (Ben)
>
> ---
> 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 5c95af2..190e970 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 e9b4608..0cff311 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 57cd88a..0b069f4 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 3f97582..ef89c7c 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 e0797cc..154a4ee 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--;
> }
> --
> 2.30.1
More information about the dm-devel
mailing list