summaryrefslogtreecommitdiffstats
path: root/rpc
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 /rpc
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 'rpc')
-rw-r--r--rpc/rpc-lib/src/libgfrpc.sym1
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c28
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h3
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c40
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h3
5 files changed, 66 insertions, 9 deletions
diff --git a/rpc/rpc-lib/src/libgfrpc.sym b/rpc/rpc-lib/src/libgfrpc.sym
index 4f42485044f..f3544e3741a 100644
--- a/rpc/rpc-lib/src/libgfrpc.sym
+++ b/rpc/rpc-lib/src/libgfrpc.sym
@@ -26,6 +26,7 @@ rpcsvc_drc_priv
rpcsvc_drc_reconfigure
rpcsvc_get_program_vector_sizer
rpcsvc_init
+rpcsvc_destroy
rpcsvc_init_options
rpcsvc_listener_destroy
rpcsvc_program_register
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index 54636dcbf00..8bb6b595175 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -159,6 +159,24 @@ out:
return msg;
}
+void
+rpc_transport_cleanup(rpc_transport_t *trans)
+{
+ if (!trans)
+ return;
+
+ trans->fini(trans);
+ GF_FREE(trans->name);
+
+ if (trans->xl)
+ pthread_mutex_destroy(&trans->lock);
+
+ if (trans->dl_handle)
+ dlclose(trans->dl_handle);
+
+ GF_FREE(trans);
+}
+
rpc_transport_t *
rpc_transport_load(glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
{
@@ -354,15 +372,7 @@ rpc_transport_load(glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
fail:
if (!success) {
- if (trans) {
- GF_FREE(trans->name);
-
- if (trans->dl_handle)
- dlclose(trans->dl_handle);
-
- GF_FREE(trans);
- }
-
+ rpc_transport_cleanup(trans);
GF_FREE(name);
return_trans = NULL;
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
index 87ea3a28dfd..d7b86b63748 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -308,4 +308,7 @@ rpc_transport_unix_options_build(dict_t **options, char *filepath,
int
rpc_transport_inet_options_build(dict_t **options, const char *hostname,
int port);
+
+void
+rpc_transport_cleanup(rpc_transport_t *);
#endif /* __RPC_TRANSPORT_H__ */
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
index 8dcc2947b33..fd531fbc1ee 100644
--- a/rpc/rpc-lib/src/rpcsvc.c
+++ b/rpc/rpc-lib/src/rpcsvc.c
@@ -37,6 +37,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
+#include <dlfcn.h>
#ifdef IPV6_DEFAULT
#include <netconfig.h>
@@ -2009,6 +2010,7 @@ rpcsvc_create_listener(rpcsvc_t *svc, dict_t *options, char *name)
listener = rpcsvc_listener_alloc(svc, trans);
if (listener == NULL) {
+ ret = -1;
goto out;
}
@@ -2016,6 +2018,7 @@ rpcsvc_create_listener(rpcsvc_t *svc, dict_t *options, char *name)
out:
if (!listener && trans) {
rpc_transport_disconnect(trans, _gf_true);
+ rpc_transport_cleanup(trans);
}
return ret;
@@ -2747,6 +2750,43 @@ rpcsvc_get_throttle(rpcsvc_t *svc)
return svc->throttle;
}
+/* Function call to cleanup resources for svc
+ */
+int
+rpcsvc_destroy(rpcsvc_t *svc)
+{
+ struct rpcsvc_auth_list *auth = NULL;
+ struct rpcsvc_auth_list *tmp = NULL;
+ rpcsvc_listener_t *listener = NULL;
+ rpcsvc_listener_t *next = NULL;
+ int ret = 0;
+
+ if (!svc)
+ return ret;
+
+ list_for_each_entry_safe(listener, next, &svc->listeners, list)
+ {
+ rpcsvc_listener_destroy(listener);
+ }
+
+ list_for_each_entry_safe(auth, tmp, &svc->authschemes, authlist)
+ {
+ list_del_init(&auth->authlist);
+ GF_FREE(auth);
+ }
+
+ rpcsvc_program_unregister(svc, &gluster_dump_prog);
+ if (svc->rxpool) {
+ mem_pool_destroy(svc->rxpool);
+ svc->rxpool = NULL;
+ }
+
+ pthread_rwlock_destroy(&svc->rpclock);
+ GF_FREE(svc);
+
+ return ret;
+}
+
/* The global RPC service initializer.
*/
rpcsvc_t *
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
index d6260ca5028..b296f9a4bde 100644
--- a/rpc/rpc-lib/src/rpcsvc.h
+++ b/rpc/rpc-lib/src/rpcsvc.h
@@ -677,4 +677,7 @@ rpcsvc_get_program_vector_sizer(rpcsvc_t *svc, uint32_t prognum,
uint32_t progver, int procnum);
void
rpcsvc_autoscale_threads(glusterfs_ctx_t *ctx, rpcsvc_t *rpc, int incr);
+
+extern int
+rpcsvc_destroy(rpcsvc_t *svc);
#endif