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 <lixiaok...@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqian...@huawei.com>
Signed-off-by: Linfeilong <linfeil...@huawei.com>
---
 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@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to