On Mon, Nov 09, 2020 at 12:32:05PM +0800, lixiaokeng wrote: > When multipath -F are executed first and multipath -v2 or > -d are executed later, asan will warn memory leaks. The > reason is that the mpp allocated in coalesce_paths isn't > freed. Here we use newmp to store mpp. If newmp need not > be copied to mpvec, we free newmp at the end of the func. > Reviewed-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> > Signed-off-by: Lixiaokeng <lixiaokeng@xxxxxxxxxx> > Signed-off-by: Zhiqiang Liu <liuzhiqiang26@xxxxxxxxxx> > Signed-off-by: Linfeilong <linfeilong@xxxxxxxxxx> > --- > libmultipath/configure.c | 40 +++++++++++++++++++++++++++++----------- > 1 file changed, 29 insertions(+), 11 deletions(-) > > diff --git a/libmultipath/configure.c b/libmultipath/configure.c > index 6fb477fc..2547e1d5 100644 > --- a/libmultipath/configure.c > +++ b/libmultipath/configure.c > @@ -1132,7 +1132,7 @@ out: > * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only > * reloaded in DM if there's a difference. This is useful during startup. > */ > -int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > +int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, > int force_reload, enum mpath_cmds cmd) > { > int ret = CP_FAIL; > @@ -1144,6 +1144,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > struct path * pp2; > vector curmp = vecs->mpvec; > vector pathvec = vecs->pathvec; > + vector newmp; > struct config *conf; > int allow_queueing; > struct bitfield *size_mismatch_seen; > @@ -1164,6 +1165,15 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > if (size_mismatch_seen == NULL) > return CP_FAIL; > > + if (mpvec) > + newmp = mpvec; > + else > + newmp = vector_alloc(); > + if (!newmp) { > + condlog(0, "can not allocate newmp"); > + goto out; > + } > + > vector_foreach_slot (pathvec, pp1, k) { > int invalid; > /* skip this path for some reason */ > @@ -1270,8 +1280,14 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > goto out; > } > } > - if (r == DOMAP_DRY) > + if (r == DOMAP_DRY) { > + if (!vector_alloc_slot(newmp)) { > + remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); > + goto out; > + } > + vector_set_slot(newmp, mpp); > continue; > + } > > if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING && > force_reload == FORCE_RELOAD_WEAK) > @@ -1307,22 +1323,22 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > print_multipath_topology(mpp, verbosity); > } > > - if (newmp) { > - if (mpp->action != ACT_REJECT) { > - if (!vector_alloc_slot(newmp)) > - goto out; > - vector_set_slot(newmp, mpp); > + if (mpp->action != ACT_REJECT) { > + if (!vector_alloc_slot(newmp)) { > + remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); > + goto out; > } > - else > - remove_map(mpp, vecs->pathvec, vecs->mpvec, > - KEEP_VEC); > + vector_set_slot(newmp, mpp); > } > + else > + remove_map(mpp, vecs->pathvec, vecs->mpvec, > + KEEP_VEC); > } > /* > * Flush maps with only dead paths (ie not in sysfs) > * Keep maps with only failed paths > */ > - if (newmp) { > + if (mpvec) { > vector_foreach_slot (newmp, mpp, i) { > char alias[WWID_SIZE]; > > @@ -1345,6 +1361,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, > ret = CP_OK; > out: > free(size_mismatch_seen); > + if (!mpvec) > + free_multipathvec(newmp, KEEP_PATHS); > return ret; > } > > -- -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel