diff options
author | Mohit Agrawal <moagrawal@redhat.com> | 2018-11-29 19:55:39 +0530 |
---|---|---|
committer | Atin Mukherjee <amukherj@redhat.com> | 2018-12-03 11:34:35 +0000 |
commit | 46c15ea8fa98bb3d92580b192f03863c2e2a2d9c (patch) | |
tree | 25462a497b273a0f963e2090adbbd928a4bb9bbc /rpc | |
parent | f77fb6d568616592ab25501c402c140d15235ca9 (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.sym | 1 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpc-transport.c | 28 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpc-transport.h | 3 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 40 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 3 |
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 |