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