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> --- 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; 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); } 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