[dm-devel] [PATCH 3/5] multipathd: add reclear_pp_from_mpp in ev_remove_path
lixiaokeng
lixiaokeng at huawei.com
Tue Aug 18 13:08:27 UTC 2020
Add reclear_pp_from_mpp in ev_remove_path to make sure that pp is cleared in mpp.
When multipathd del path xxx, multipathd -v2, multipathd add path xxx and multipath -U
dm-x are executed simultaneously, multipath -U dm-x will case coredump.
The reason is that there are two paths with same dev_t in dm_table. The process
is as follows:
multipathd del path xxx(such as sde whose dev_t is 8:64):
cli_del_path
->ev_remove_path
->domap //dm_table in kernel will be reloaded and doesn't contain 8:64.
//Then multipath -v2 is executed, and the dm_table in kernel
//will be reloaded and contains 8:64.
->setup_multipath
->update_multipath_strings
->update_multipath_table
->dm_get_map //get params with 8:64
->disassemble_map //pp1 will be saved mpp->pg
->delete pp1 in pathvec
->clear_ref_from_mpp //pp is cleared in mpp->paths but still saved in
//mpp->pg
->free_paths //pp1 is freed but still exist in mpp->pg
multipathd add path sde
cli_add_path
->store_pathinfo //alloc pp2 (dev_t is 8:64), and store it to gvecs->pathvec
->ev_add_path
->adopt_paths
->update_mpp_paths //pp1 is found in mpp->pg and its dev_t is
//8:64 and dev is not sde (cased by free).
//it will be stored in mpp->paths.
->pp2 is stored to mpp->paths
->setup_map //params with two 8:64
->domap //dm_table is reloaded and contains two 8:64
multipath -U dm-x(sde is one path of dm-x)
main
->check_usable_paths
->dm_get_maps //get params with two 8:64
->disassemble_map //alloc pp3, and pp3 is saved twice in mpp->pg
->free_multipath(mpp, FREE_PATHS) //double free
Here, we add that pp1 in mpp->pg is cleared in clear_ref_from_mpp.
Reported-by: Tianxiong Lu <lutianxiong at huawei.com>
Signed-off-by: lixiaokeng <lixiaokeng at huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26 at huawei.com>
---
multipathd/main.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/multipathd/main.c b/multipathd/main.c
index 9ec65856..a1db17a0 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1059,6 +1059,32 @@ fail:
return 1;
}
+static
+void reclear_pp_from_mpp(struct path * pp, struct vectors * vecs)
+{
+ struct multipath * mpp = NULL;
+ struct pathgroup * pgp;
+ int i = -1;
+ int j = 0;
+ int is_log = 0;
+
+ mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
+ if(!!mpp) {
+ if ((i = find_slot(mpp->paths, (void *)pp)) != -1) {
+ vector_del_slot(mpp->paths, i);
+ is_log = 1;
+ }
+ vector_foreach_slot (mpp->pg, pgp, j) {
+ if ((i = find_slot(pgp->paths, (void *)pp)) != -1) {
+ vector_del_slot(pgp->paths, i);
+ is_log = 1;
+ }
+ }
+ if (is_log)
+ condlog(2, "%s: reclear path from mpp %s", pp->dev, mpp->alias);
+ }
+}
+
static int
uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
{
@@ -1186,6 +1212,7 @@ out:
if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
vector_del_slot(vecs->pathvec, i);
+ reclear_pp_from_mpp(pp, vecs);
free_path(pp);
return retval;
--
More information about the dm-devel
mailing list