Hi lixiaokeng, On Thu, 2020-10-22 at 15:28 +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. > > Signed-off-by: Lixiaokeng <lixiaokeng@xxxxxxxxxx> > Signed-off-by: Zhiqiang Liu <liuzhiqiang26@xxxxxxxxxx> > Signed-off-by: Linfeilong <linfeilong@xxxxxxxxxx> Thanks. Please see below. > --- > libmultipath/configure.c | 66 +++++++++++++++++++++++++------------- > -- > 1 file changed, 41 insertions(+), 25 deletions(-) > > diff --git a/libmultipath/configure.c b/libmultipath/configure.c > index 6fb477fc..9d6eeba1 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,10 +1144,20 @@ int coalesce_paths (struct vectors * vecs, > vector newmp, char * refwwid, > struct path * pp2; > vector curmp = vecs->mpvec; > vector pathvec = vecs->pathvec; > + vector newmp = NULL; This initialization is not necessary. > struct config *conf; > int allow_queueing; > struct bitfield *size_mismatch_seen; > > + if (mpvec) > + newmp = mpvec; > + else > + newmp = vector_alloc(); > + if (!newmp) { > + condlog(0, "can not allocate newmp"); > + return ret; > + } > + > /* ignore refwwid if it's empty */ > if (refwwid && !strlen(refwwid)) > refwwid = NULL; > @@ -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,44 +1323,44 @@ 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) { > - vector_foreach_slot (newmp, mpp, i) { > - char alias[WWID_SIZE]; > + vector_foreach_slot (newmp, mpp, i) { > + char alias[WWID_SIZE]; > > - if (!deadmap(mpp)) > - continue; > + if (!deadmap(mpp)) > + continue; > > - strlcpy(alias, mpp->alias, WWID_SIZE); > + strlcpy(alias, mpp->alias, WWID_SIZE); > > - vector_del_slot(newmp, i); > - i--; > - remove_map(mpp, vecs->pathvec, vecs->mpvec, > KEEP_VEC); > + vector_del_slot(newmp, i); > + i--; > + remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); > > - if (dm_flush_map(alias)) > - condlog(2, "%s: remove failed (dead)", > - alias); > - else > - condlog(2, "%s: remove (dead)", alias); > - } > + if (dm_flush_map(alias)) > + condlog(2, "%s: remove failed (dead)", > + alias); > + else > + condlog(2, "%s: remove (dead)", alias); Previously, this code, which flushes maps that aren't valid any more, would only be called from multipathd() -> reconfigure(), because in all other cases newmp was NULL. AFAICS, you will now call dm_flush_map() even if called with newmp==NULL (this means, from cli_add_map(), or from multipath, even if called with CMD_DRY_RUN). I don't think that's what we want. Regards, Martin -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel