a3470f
From ad7ea067e2f7f9e7fb533ddf67e9c1f3c70e222f Mon Sep 17 00:00:00 2001
a3470f
From: Mohit Agrawal <moagrawa@redhat.com>
a3470f
Date: Thu, 7 Dec 2017 10:32:05 +0530
a3470f
Subject: [PATCH 105/128] glusterd : Fix glusterd mem leaks
a3470f
a3470f
Problem:   glusterd eats a huge amount of meory during volume set/stop/start.
a3470f
a3470f
Solution:  At the time of compare graph topology create a graph and populate
a3470f
           key values in the dictionary, after finished graph comparison we
a3470f
           do destroy the new graph.At the time of construct graph we don't take
a3470f
           any reference and for server xlators we do take reference in
a3470f
           server_setvolume so in glusterd we do take reference after prepare
a3470f
           a new graph while we do create a graph to compare graph topology.
a3470f
a3470f
> BUG: 1520245
a3470f
> Change-Id: I573133d57771b7dc431a04422c5001a06b7dda9a
a3470f
> Reviewed on https://review.gluster.org/#/c/18915/
a3470f
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
a3470f
> (cherry pick from commit e016bcaf8171373cbc327faf42a6b2f2c5449b0e)
a3470f
a3470f
BUG: 1512470
a3470f
Change-Id: Id9aa37146f3ae887f4d06492edad6dedcafc6681
a3470f
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
a3470f
Reviewed-on: https://code.engineering.redhat.com/gerrit/126229
a3470f
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
a3470f
Tested-by: RHGS Build Bot <nigelb@redhat.com>
a3470f
---
a3470f
 xlators/mgmt/glusterd/src/glusterd-handshake.c |  3 +++
a3470f
 xlators/mgmt/glusterd/src/glusterd-utils.c     | 34 ++++++++++++++++++++++++++
a3470f
 2 files changed, 37 insertions(+)
a3470f
a3470f
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
a3470f
index 8dfb528..35aeca3 100644
a3470f
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
a3470f
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
a3470f
@@ -1256,6 +1256,9 @@ out:
a3470f
         if (rsp.hndsk.hndsk_val)
a3470f
                 GF_FREE (rsp.hndsk.hndsk_val);
a3470f
 
a3470f
+        if (args_dict)
a3470f
+                dict_unref (args_dict);
a3470f
+
a3470f
         return ret;
a3470f
 }
a3470f
 
a3470f
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
a3470f
index 504e5af..1434d64 100644
a3470f
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
a3470f
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
a3470f
@@ -8971,6 +8971,36 @@ glusterd_defrag_volume_status_update (glusterd_volinfo_t *volinfo,
a3470f
 
a3470f
         return ret;
a3470f
 }
a3470f
+/*
a3470f
+   The function is required to take dict ref for every xlator at graph.
a3470f
+   At the time of compare graph topology create a graph and populate
a3470f
+   key values in the dictionary, after finished graph comparison we do destroy
a3470f
+   the new graph.At the time of construct graph we don't take any reference
a3470f
+   so to avoid leak due to ref counter underflow we need to call dict_ref here.
a3470f
+
a3470f
+*/
a3470f
+
a3470f
+void
a3470f
+glusterd_graph_take_reference (xlator_t *tree)
a3470f
+{        xlator_t *trav = tree;
a3470f
+         xlator_t *prev = tree;
a3470f
+
a3470f
+        if (!tree) {
a3470f
+                gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND,
a3470f
+                        "Translator tree not found");
a3470f
+                return;
a3470f
+        }
a3470f
+
a3470f
+        while (prev) {
a3470f
+                trav = prev->next;
a3470f
+                if (prev->options)
a3470f
+                        dict_ref (prev->options);
a3470f
+                prev = trav;
a3470f
+        }
a3470f
+        return;
a3470f
+}
a3470f
+
a3470f
+
a3470f
 
a3470f
 int
a3470f
 glusterd_check_topology_identical (const char   *filename1,
a3470f
@@ -9018,11 +9048,15 @@ glusterd_check_topology_identical (const char   *filename1,
a3470f
         if (grph1 == NULL)
a3470f
                 goto out;
a3470f
 
a3470f
+        glusterd_graph_take_reference (grph1->first);
a3470f
+
a3470f
         /* create the graph for filename2 */
a3470f
         grph2 = glusterfs_graph_construct(fp2);
a3470f
         if (grph2 == NULL)
a3470f
                 goto out;
a3470f
 
a3470f
+        glusterd_graph_take_reference (grph2->first);
a3470f
+
a3470f
         /* compare the graph topology */
a3470f
         *identical = is_graph_topology_equal(grph1, grph2);
a3470f
         ret = 0; /* SUCCESS */
a3470f
-- 
a3470f
1.8.3.1
a3470f