summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorMohit Agrawal <moagrawal@redhat.com>2018-11-29 19:55:39 +0530
committerAtin Mukherjee <amukherj@redhat.com>2018-12-03 11:34:35 +0000
commit46c15ea8fa98bb3d92580b192f03863c2e2a2d9c (patch)
tree25462a497b273a0f963e2090adbbd928a4bb9bbc /xlators
parentf77fb6d568616592ab25501c402c140d15235ca9 (diff)
server: Resolve memory leak path in server_init
Problem: 1) server_init does not cleanup allocate resources while it is failed before return error 2) dict leak at the time of graph destroying Solution: 1) free resources in case of server_init is failed 2) Take dict_ref of graph xlator before destroying the graph to avoid leak Change-Id: I9e31e156b9ed6bebe622745a8be0e470774e3d15 fixes: bz#1654917 Signed-off-by: Mohit Agrawal <moagrawal@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c33
-rw-r--r--xlators/protocol/server/src/server.c54
2 files changed, 47 insertions, 40 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 2deda29..cdac6d5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -9301,35 +9301,6 @@ glusterd_defrag_volume_status_update(glusterd_volinfo_t *volinfo,
return ret;
}
-/*
- The function is required to take dict ref for every xlator at graph.
- At the time of compare graph topology create a graph and populate
- key values in the dictionary, after finished graph comparison we do destroy
- the new graph.At the time of construct graph we don't take any reference
- so to avoid leak due to ref counter underflow we need to call dict_ref here.
-
-*/
-
-void
-glusterd_graph_take_reference(xlator_t *tree)
-{
- xlator_t *trav = tree;
- xlator_t *prev = tree;
-
- if (!tree) {
- gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND,
- "Translator tree not found");
- return;
- }
-
- while (prev) {
- trav = prev->next;
- if (prev->options)
- dict_ref(prev->options);
- prev = trav;
- }
- return;
-}
int
glusterd_check_topology_identical(const char *filename1, const char *filename2,
@@ -9376,14 +9347,14 @@ glusterd_check_topology_identical(const char *filename1, const char *filename2,
if (grph1 == NULL)
goto out;
- glusterd_graph_take_reference(grph1->first);
+ gluster_graph_take_reference(grph1->first);
/* create the graph for filename2 */
grph2 = glusterfs_graph_construct(fp2);
if (grph2 == NULL)
goto out;
- glusterd_graph_take_reference(grph2->first);
+ gluster_graph_take_reference(grph2->first);
/* compare the graph topology */
*identical = is_graph_topology_equal(grph1, grph2);
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index 77e5d74..81aa72f 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -986,6 +986,49 @@ server_dump_metrics(xlator_t *this, int fd)
return 0;
}
+void
+server_cleanup(xlator_t *this, server_conf_t *conf)
+{
+ if (!this || !conf)
+ return;
+
+ LOCK_DESTROY(&conf->itable_lock);
+ pthread_mutex_destroy(&conf->mutex);
+
+ if (this->ctx->event_pool) {
+ /* Free the event pool */
+ (void)event_pool_destroy(this->ctx->event_pool);
+ }
+
+ if (dict_get(this->options, "config-directory")) {
+ GF_FREE(conf->conf_dir);
+ conf->conf_dir = NULL;
+ }
+
+ if (conf->child_status) {
+ GF_FREE(conf->child_status);
+ conf->child_status = NULL;
+ }
+
+ if (this->ctx->statedump_path) {
+ GF_FREE(this->ctx->statedump_path);
+ this->ctx->statedump_path = NULL;
+ }
+
+ if (conf->auth_modules) {
+ gf_auth_fini(conf->auth_modules);
+ dict_unref(conf->auth_modules);
+ }
+
+ if (conf->rpc) {
+ (void)rpcsvc_destroy(conf->rpc);
+ conf->rpc = NULL;
+ }
+
+ GF_FREE(conf);
+ this->private = NULL;
+}
+
int
server_init(xlator_t *this)
{
@@ -1061,6 +1104,7 @@ server_init(xlator_t *this)
ret = gf_auth_init(this, conf->auth_modules);
if (ret) {
dict_unref(conf->auth_modules);
+ conf->auth_modules = NULL;
goto out;
}
@@ -1239,15 +1283,7 @@ out:
if (this != NULL) {
this->fini(this);
}
-
- if (conf && conf->rpc) {
- rpcsvc_listener_t *listener, *next;
- list_for_each_entry_safe(listener, next, &conf->rpc->listeners,
- list)
- {
- rpcsvc_listener_destroy(listener);
- }
- }
+ server_cleanup(this, conf);
}
return ret;