device-mapper-multipath/0136-libmultipath-merge-update_multipath_table-and-update.patch

230 lines
7.1 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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--;
}