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 | 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@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to