* [dm-devel] [PATCH v2] libmultipath: fix memory leaks in coalesce_paths
@ 2020-10-22 7:28 lixiaokeng
2020-11-01 21:23 ` Martin Wilck
0 siblings, 1 reply; 3+ messages in thread
From: lixiaokeng @ 2020-10-22 7:28 UTC (permalink / raw)
To: Christophe Varoqui, Benjamin Marzinski, Martin Wilck,
dm-devel mailing list
Cc: linfeilong, liuzhiqiang (I)
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@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Signed-off-by: Linfeilong <linfeilong@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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [dm-devel] [PATCH v2] libmultipath: fix memory leaks in coalesce_paths
2020-10-22 7:28 [dm-devel] [PATCH v2] libmultipath: fix memory leaks in coalesce_paths lixiaokeng
@ 2020-11-01 21:23 ` Martin Wilck
2020-11-02 2:35 ` lixiaokeng
0 siblings, 1 reply; 3+ messages in thread
From: Martin Wilck @ 2020-11-01 21:23 UTC (permalink / raw)
To: lixiaokeng, Christophe Varoqui, Benjamin Marzinski,
dm-devel mailing list
Cc: linfeilong, liuzhiqiang (I)
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@huawei.com>
> Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
> Signed-off-by: Linfeilong <linfeilong@huawei.com>
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@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [dm-devel] [PATCH v2] libmultipath: fix memory leaks in coalesce_paths
2020-11-01 21:23 ` Martin Wilck
@ 2020-11-02 2:35 ` lixiaokeng
0 siblings, 0 replies; 3+ messages in thread
From: lixiaokeng @ 2020-11-02 2:35 UTC (permalink / raw)
To: Martin Wilck, Christophe Varoqui, Benjamin Marzinski,
dm-devel mailing list
Cc: linfeilong, liuzhiqiang (I)
On 2020/11/2 5:23, Martin Wilck wrote:
> 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.
Hi
Thanks for your review. I will change my patch to make sure dm_flush_map()
is called only when mpvec (newmp in old code) is not NULL. Thanks for your
advice again.
Regards,
Lixiaokeng
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-11-02 2:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-22 7:28 [dm-devel] [PATCH v2] libmultipath: fix memory leaks in coalesce_paths lixiaokeng
2020-11-01 21:23 ` Martin Wilck
2020-11-02 2:35 ` lixiaokeng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).