e3c68b
From df6523ed3c5267624197b52edcb553fc2d8a08f2 Mon Sep 17 00:00:00 2001
e3c68b
From: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
Date: Tue, 26 Feb 2019 18:04:18 +0530
e3c68b
Subject: [PATCH 102/124] rpc/transport: Missing a ref on dict while creating
e3c68b
 transport object
e3c68b
e3c68b
while creating rpc_tranpsort object, we store a dictionary without
e3c68b
taking a ref on dict but it does an unref during the cleaning of the
e3c68b
transport object.
e3c68b
e3c68b
So the rpc layer expect the caller to take a ref on the dictionary
e3c68b
before passing dict to rpc layer. This leads to a lot of confusion
e3c68b
across the code base and leads to ref leaks.
e3c68b
e3c68b
Semantically, this is not correct. It is the rpc layer responsibility
e3c68b
to take a ref when storing it, and free during the cleanup.
e3c68b
e3c68b
I'm listing down the total issues or leaks across the code base because
e3c68b
of this confusion. These issues are currently present in the upstream
e3c68b
master.
e3c68b
e3c68b
1) changelog_rpc_client_init
e3c68b
e3c68b
2) quota_enforcer_init
e3c68b
e3c68b
3) rpcsvc_create_listeners : when there are two transport, like tcp,rdma.
e3c68b
e3c68b
4) quotad_aggregator_init
e3c68b
e3c68b
5) glusterd: init
e3c68b
e3c68b
6) nfs3_init_state
e3c68b
e3c68b
7) server: init
e3c68b
e3c68b
8) client:init
e3c68b
e3c68b
This patch does the cleanup according to the semantics.
e3c68b
e3c68b
Backport of : https://review.gluster.org/#/c/glusterfs/+/22266/
e3c68b
e3c68b
>Change-Id: I46373af9630373eb375ee6de0e6f2bbe2a677425
e3c68b
>updates: bz#1659708
e3c68b
>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
e3c68b
Change-Id: Iff978497e11592fbebfa4b683fdc56698b782859
e3c68b
BUG: 1471742
e3c68b
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
Reviewed-on: https://code.engineering.redhat.com/gerrit/167847
e3c68b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e3c68b
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e3c68b
---
e3c68b
 api/src/glfs-mgmt.c                                | 10 ++++--
e3c68b
 cli/src/cli.c                                      | 20 +++++++-----
e3c68b
 glusterfsd/src/glusterfsd-mgmt.c                   | 18 ++++++++--
e3c68b
 rpc/rpc-lib/src/rpc-clnt.c                         |  2 --
e3c68b
 rpc/rpc-lib/src/rpc-transport.c                    | 38 +++++++---------------
e3c68b
 rpc/rpc-lib/src/rpc-transport.h                    |  4 +--
e3c68b
 rpc/rpc-lib/src/rpcsvc.c                           | 13 ++------
e3c68b
 rpc/rpc-lib/src/rpcsvc.h                           |  2 +-
e3c68b
 .../features/changelog/src/changelog-rpc-common.c  |  9 +++--
e3c68b
 .../snapview-server/src/snapview-server-mgmt.c     |  8 ++++-
e3c68b
 xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c     |  8 ++++-
e3c68b
 xlators/mgmt/glusterd/src/glusterd-handler.c       | 18 ++++++----
e3c68b
 xlators/mgmt/glusterd/src/glusterd-rebalance.c     |  8 ++++-
e3c68b
 xlators/mgmt/glusterd/src/glusterd-utils.c         |  9 +++--
e3c68b
 xlators/mgmt/glusterd/src/glusterd.c               |  6 +++-
e3c68b
 xlators/nfs/server/src/acl3.c                      |  5 +++
e3c68b
 xlators/nfs/server/src/mount3.c                    |  5 +++
e3c68b
 xlators/nfs/server/src/nlm4.c                      |  7 ++++
e3c68b
 18 files changed, 119 insertions(+), 71 deletions(-)
e3c68b
e3c68b
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
e3c68b
index d502b4f..7476d5b 100644
e3c68b
--- a/api/src/glfs-mgmt.c
e3c68b
+++ b/api/src/glfs-mgmt.c
e3c68b
@@ -1015,6 +1015,10 @@ glfs_mgmt_init(struct glfs *fs)
e3c68b
     if (ctx->mgmt)
e3c68b
         return 0;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     if (cmd_args->volfile_server_port)
e3c68b
         port = cmd_args->volfile_server_port;
e3c68b
 
e3c68b
@@ -1029,11 +1033,11 @@ glfs_mgmt_init(struct glfs *fs)
e3c68b
 
e3c68b
     if (cmd_args->volfile_server_transport &&
e3c68b
         !strcmp(cmd_args->volfile_server_transport, "unix")) {
e3c68b
-        ret = rpc_transport_unix_options_build(&options, host, 0);
e3c68b
+        ret = rpc_transport_unix_options_build(options, host, 0);
e3c68b
     } else {
e3c68b
         xlator_cmdline_option_t *opt = find_xlator_option_in_cmd_args_t(
e3c68b
             "address-family", cmd_args);
e3c68b
-        ret = rpc_transport_inet_options_build(&options, host, port,
e3c68b
+        ret = rpc_transport_inet_options_build(options, host, port,
e3c68b
                                                (opt ? opt->value : NULL));
e3c68b
     }
e3c68b
 
e3c68b
@@ -1075,5 +1079,7 @@ glfs_mgmt_init(struct glfs *fs)
e3c68b
 
e3c68b
     ret = rpc_clnt_start(rpc);
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/cli/src/cli.c b/cli/src/cli.c
e3c68b
index c33d152..ff39a98 100644
e3c68b
--- a/cli/src/cli.c
e3c68b
+++ b/cli/src/cli.c
e3c68b
@@ -661,9 +661,8 @@ cli_quotad_clnt_rpc_init(void)
e3c68b
 
e3c68b
     global_quotad_rpc = rpc;
e3c68b
 out:
e3c68b
-    if (ret) {
e3c68b
-        if (rpc_opts)
e3c68b
-            dict_unref(rpc_opts);
e3c68b
+    if (rpc_opts) {
e3c68b
+        dict_unref(rpc_opts);
e3c68b
     }
e3c68b
     return rpc;
e3c68b
 }
e3c68b
@@ -685,6 +684,10 @@ cli_rpc_init(struct cli_state *state)
e3c68b
     this = THIS;
e3c68b
     cli_rpc_prog = &cli_prog;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     /* If address family specified in CLI */
e3c68b
     if (state->address_family) {
e3c68b
         addr_family = state->address_family;
e3c68b
@@ -699,7 +702,7 @@ cli_rpc_init(struct cli_state *state)
e3c68b
                "Connecting to glusterd using "
e3c68b
                "sockfile %s",
e3c68b
                state->glusterd_sock);
e3c68b
-        ret = rpc_transport_unix_options_build(&options, state->glusterd_sock,
e3c68b
+        ret = rpc_transport_unix_options_build(options, state->glusterd_sock,
e3c68b
                                                0);
e3c68b
         if (ret)
e3c68b
             goto out;
e3c68b
@@ -709,10 +712,6 @@ cli_rpc_init(struct cli_state *state)
e3c68b
                "%s",
e3c68b
                state->remote_host);
e3c68b
 
e3c68b
-        options = dict_new();
e3c68b
-        if (!options)
e3c68b
-            goto out;
e3c68b
-
e3c68b
         ret = dict_set_str(options, "remote-host", state->remote_host);
e3c68b
         if (ret)
e3c68b
             goto out;
e3c68b
@@ -731,7 +730,7 @@ cli_rpc_init(struct cli_state *state)
e3c68b
         gf_log("cli", GF_LOG_DEBUG,
e3c68b
                "Connecting to glusterd using "
e3c68b
                "default socket");
e3c68b
-        ret = rpc_transport_unix_options_build(&options,
e3c68b
+        ret = rpc_transport_unix_options_build(options,
e3c68b
                                                DEFAULT_GLUSTERD_SOCKFILE, 0);
e3c68b
         if (ret)
e3c68b
             goto out;
e3c68b
@@ -749,6 +748,9 @@ cli_rpc_init(struct cli_state *state)
e3c68b
 
e3c68b
     ret = rpc_clnt_start(rpc);
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
+
e3c68b
     if (ret) {
e3c68b
         if (rpc)
e3c68b
             rpc_clnt_unref(rpc);
e3c68b
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
index a89c980..1d2cd1a 100644
e3c68b
--- a/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
+++ b/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
@@ -2781,7 +2781,11 @@ glusterfs_listener_init(glusterfs_ctx_t *ctx)
e3c68b
     if (!cmd_args->sock_file)
e3c68b
         return 0;
e3c68b
 
e3c68b
-    ret = rpcsvc_transport_unix_options_build(&options, cmd_args->sock_file);
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    ret = rpcsvc_transport_unix_options_build(options, cmd_args->sock_file);
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
 
e3c68b
@@ -2808,6 +2812,8 @@ glusterfs_listener_init(glusterfs_ctx_t *ctx)
e3c68b
     ctx->listener = rpc;
e3c68b
 
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
@@ -2889,6 +2895,10 @@ glusterfs_mgmt_init(glusterfs_ctx_t *ctx)
e3c68b
     if (ctx->mgmt)
e3c68b
         return 0;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     LOCK_INIT(&ctx->volfile_lock);
e3c68b
 
e3c68b
     if (cmd_args->volfile_server_port)
e3c68b
@@ -2898,10 +2908,10 @@ glusterfs_mgmt_init(glusterfs_ctx_t *ctx)
e3c68b
 
e3c68b
     if (cmd_args->volfile_server_transport &&
e3c68b
         !strcmp(cmd_args->volfile_server_transport, "unix")) {
e3c68b
-        ret = rpc_transport_unix_options_build(&options, host, 0);
e3c68b
+        ret = rpc_transport_unix_options_build(options, host, 0);
e3c68b
     } else {
e3c68b
         opt = find_xlator_option_in_cmd_args_t("address-family", cmd_args);
e3c68b
-        ret = rpc_transport_inet_options_build(&options, host, port,
e3c68b
+        ret = rpc_transport_inet_options_build(options, host, port,
e3c68b
                                                (opt ? opt->value : NULL));
e3c68b
     }
e3c68b
     if (ret)
e3c68b
@@ -2950,6 +2960,8 @@ glusterfs_mgmt_init(glusterfs_ctx_t *ctx)
e3c68b
 
e3c68b
     ret = rpc_clnt_start(rpc);
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c
e3c68b
index 6f47515..b04eaed 100644
e3c68b
--- a/rpc/rpc-lib/src/rpc-clnt.c
e3c68b
+++ b/rpc/rpc-lib/src/rpc-clnt.c
e3c68b
@@ -1125,8 +1125,6 @@ rpc_clnt_new(dict_t *options, xlator_t *owner, char *name,
e3c68b
         mem_pool_destroy(rpc->saved_frames_pool);
e3c68b
         GF_FREE(rpc);
e3c68b
         rpc = NULL;
e3c68b
-        if (options)
e3c68b
-            dict_unref(options);
e3c68b
         goto out;
e3c68b
     }
e3c68b
 
e3c68b
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
e3c68b
index 4beaaf9..bed1f8c 100644
e3c68b
--- a/rpc/rpc-lib/src/rpc-transport.c
e3c68b
+++ b/rpc/rpc-lib/src/rpc-transport.c
e3c68b
@@ -168,6 +168,11 @@ rpc_transport_cleanup(rpc_transport_t *trans)
e3c68b
     if (trans->fini)
e3c68b
         trans->fini(trans);
e3c68b
 
e3c68b
+    if (trans->options) {
e3c68b
+        dict_unref(trans->options);
e3c68b
+        trans->options = NULL;
e3c68b
+    }
e3c68b
+
e3c68b
     GF_FREE(trans->name);
e3c68b
 
e3c68b
     if (trans->xl)
e3c68b
@@ -352,7 +357,7 @@ rpc_transport_load(glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
e3c68b
         }
e3c68b
     }
e3c68b
 
e3c68b
-    trans->options = options;
e3c68b
+    trans->options = dict_ref(options);
e3c68b
 
e3c68b
     pthread_mutex_init(&trans->lock, NULL);
e3c68b
     trans->xl = this;
e3c68b
@@ -591,19 +596,14 @@ out:
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
-rpc_transport_unix_options_build(dict_t **options, char *filepath,
e3c68b
+rpc_transport_unix_options_build(dict_t *dict, char *filepath,
e3c68b
                                  int frame_timeout)
e3c68b
 {
e3c68b
-    dict_t *dict = NULL;
e3c68b
     char *fpath = NULL;
e3c68b
     int ret = -1;
e3c68b
 
e3c68b
     GF_ASSERT(filepath);
e3c68b
-    GF_ASSERT(options);
e3c68b
-
e3c68b
-    dict = dict_new();
e3c68b
-    if (!dict)
e3c68b
-        goto out;
e3c68b
+    GF_VALIDATE_OR_GOTO("rpc-transport", dict, out);
e3c68b
 
e3c68b
     fpath = gf_strdup(filepath);
e3c68b
     if (!fpath) {
e3c68b
@@ -638,20 +638,14 @@ rpc_transport_unix_options_build(dict_t **options, char *filepath,
e3c68b
         if (ret)
e3c68b
             goto out;
e3c68b
     }
e3c68b
-
e3c68b
-    *options = dict;
e3c68b
 out:
e3c68b
-    if (ret && dict) {
e3c68b
-        dict_unref(dict);
e3c68b
-    }
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
-rpc_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
-                                 int port, char *af)
e3c68b
+rpc_transport_inet_options_build(dict_t *dict, const char *hostname, int port,
e3c68b
+                                 char *af)
e3c68b
 {
e3c68b
-    dict_t *dict = NULL;
e3c68b
     char *host = NULL;
e3c68b
     int ret = -1;
e3c68b
 #ifdef IPV6_DEFAULT
e3c68b
@@ -660,13 +654,9 @@ rpc_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
     char *addr_family = "inet";
e3c68b
 #endif
e3c68b
 
e3c68b
-    GF_ASSERT(options);
e3c68b
     GF_ASSERT(hostname);
e3c68b
     GF_ASSERT(port >= 1024);
e3c68b
-
e3c68b
-    dict = dict_new();
e3c68b
-    if (!dict)
e3c68b
-        goto out;
e3c68b
+    GF_VALIDATE_OR_GOTO("rpc-transport", dict, out);
e3c68b
 
e3c68b
     host = gf_strdup((char *)hostname);
e3c68b
     if (!host) {
e3c68b
@@ -702,12 +692,6 @@ rpc_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
                "failed to set trans-type with socket");
e3c68b
         goto out;
e3c68b
     }
e3c68b
-
e3c68b
-    *options = dict;
e3c68b
 out:
e3c68b
-    if (ret && dict) {
e3c68b
-        dict_unref(dict);
e3c68b
-    }
e3c68b
-
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
e3c68b
index 9e75d1a..64b7e9b 100644
e3c68b
--- a/rpc/rpc-lib/src/rpc-transport.h
e3c68b
+++ b/rpc/rpc-lib/src/rpc-transport.h
e3c68b
@@ -303,11 +303,11 @@ rpc_transport_keepalive_options_set(dict_t *options, int32_t interval,
e3c68b
                                     int32_t time, int32_t timeout);
e3c68b
 
e3c68b
 int
e3c68b
-rpc_transport_unix_options_build(dict_t **options, char *filepath,
e3c68b
+rpc_transport_unix_options_build(dict_t *options, char *filepath,
e3c68b
                                  int frame_timeout);
e3c68b
 
e3c68b
 int
e3c68b
-rpc_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
+rpc_transport_inet_options_build(dict_t *options, const char *hostname,
e3c68b
                                  int port, char *af);
e3c68b
 
e3c68b
 void
e3c68b
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
e3c68b
index 74373c4..5a35139 100644
e3c68b
--- a/rpc/rpc-lib/src/rpcsvc.c
e3c68b
+++ b/rpc/rpc-lib/src/rpcsvc.c
e3c68b
@@ -2615,18 +2615,13 @@ rpcsvc_reconfigure_options(rpcsvc_t *svc, dict_t *options)
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
-rpcsvc_transport_unix_options_build(dict_t **options, char *filepath)
e3c68b
+rpcsvc_transport_unix_options_build(dict_t *dict, char *filepath)
e3c68b
 {
e3c68b
-    dict_t *dict = NULL;
e3c68b
     char *fpath = NULL;
e3c68b
     int ret = -1;
e3c68b
 
e3c68b
     GF_ASSERT(filepath);
e3c68b
-    GF_ASSERT(options);
e3c68b
-
e3c68b
-    dict = dict_new();
e3c68b
-    if (!dict)
e3c68b
-        goto out;
e3c68b
+    GF_VALIDATE_OR_GOTO("rpcsvc", dict, out);
e3c68b
 
e3c68b
     fpath = gf_strdup(filepath);
e3c68b
     if (!fpath) {
e3c68b
@@ -2649,13 +2644,9 @@ rpcsvc_transport_unix_options_build(dict_t **options, char *filepath)
e3c68b
     ret = dict_set_str(dict, "transport-type", "socket");
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
-
e3c68b
-    *options = dict;
e3c68b
 out:
e3c68b
     if (ret) {
e3c68b
         GF_FREE(fpath);
e3c68b
-        if (dict)
e3c68b
-            dict_unref(dict);
e3c68b
     }
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
e3c68b
index 34045ce..a51edc7 100644
e3c68b
--- a/rpc/rpc-lib/src/rpcsvc.h
e3c68b
+++ b/rpc/rpc-lib/src/rpcsvc.h
e3c68b
@@ -665,7 +665,7 @@ rpcsvc_actor_t *
e3c68b
 rpcsvc_program_actor(rpcsvc_request_t *req);
e3c68b
 
e3c68b
 int
e3c68b
-rpcsvc_transport_unix_options_build(dict_t **options, char *filepath);
e3c68b
+rpcsvc_transport_unix_options_build(dict_t *options, char *filepath);
e3c68b
 int
e3c68b
 rpcsvc_set_allow_insecure(rpcsvc_t *svc, dict_t *options);
e3c68b
 int
e3c68b
diff --git a/xlators/features/changelog/src/changelog-rpc-common.c b/xlators/features/changelog/src/changelog-rpc-common.c
e3c68b
index cf35175..dcdcfb1 100644
e3c68b
--- a/xlators/features/changelog/src/changelog-rpc-common.c
e3c68b
+++ b/xlators/features/changelog/src/changelog-rpc-common.c
e3c68b
@@ -47,7 +47,7 @@ changelog_rpc_client_init(xlator_t *this, void *cbkdata, char *sockfile,
e3c68b
     if (!options)
e3c68b
         goto error_return;
e3c68b
 
e3c68b
-    ret = rpc_transport_unix_options_build(&options, sockfile, 0);
e3c68b
+    ret = rpc_transport_unix_options_build(options, sockfile, 0);
e3c68b
     if (ret) {
e3c68b
         gf_msg(this->name, GF_LOG_ERROR, 0, CHANGELOG_MSG_RPC_BUILD_ERROR,
e3c68b
                "failed to build rpc options");
e3c68b
@@ -73,6 +73,7 @@ changelog_rpc_client_init(xlator_t *this, void *cbkdata, char *sockfile,
e3c68b
         goto dealloc_rpc_clnt;
e3c68b
     }
e3c68b
 
e3c68b
+    dict_unref(options);
e3c68b
     return rpc;
e3c68b
 
e3c68b
 dealloc_rpc_clnt:
e3c68b
@@ -303,7 +304,11 @@ changelog_rpc_server_init(xlator_t *this, char *sockfile, void *cbkdata,
e3c68b
     if (!cbkdata)
e3c68b
         cbkdata = this;
e3c68b
 
e3c68b
-    ret = rpcsvc_transport_unix_options_build(&options, sockfile);
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        return NULL;
e3c68b
+
e3c68b
+    ret = rpcsvc_transport_unix_options_build(options, sockfile);
e3c68b
     if (ret)
e3c68b
         goto dealloc_dict;
e3c68b
 
e3c68b
diff --git a/xlators/features/snapview-server/src/snapview-server-mgmt.c b/xlators/features/snapview-server/src/snapview-server-mgmt.c
e3c68b
index b608cdf..bc415ef 100644
e3c68b
--- a/xlators/features/snapview-server/src/snapview-server-mgmt.c
e3c68b
+++ b/xlators/features/snapview-server/src/snapview-server-mgmt.c
e3c68b
@@ -101,8 +101,12 @@ svs_mgmt_init(xlator_t *this)
e3c68b
     if (cmd_args->volfile_server)
e3c68b
         host = cmd_args->volfile_server;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     opt = find_xlator_option_in_cmd_args_t("address-family", cmd_args);
e3c68b
-    ret = rpc_transport_inet_options_build(&options, host, port,
e3c68b
+    ret = rpc_transport_inet_options_build(options, host, port,
e3c68b
                                            (opt != NULL ? opt->value : NULL));
e3c68b
     if (ret) {
e3c68b
         gf_msg(this->name, GF_LOG_ERROR, 0, SVS_MSG_BUILD_TRNSPRT_OPT_FAILED,
e3c68b
@@ -145,6 +149,8 @@ svs_mgmt_init(xlator_t *this)
e3c68b
     gf_msg_debug(this->name, 0, "svs mgmt init successful");
e3c68b
 
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     if (ret)
e3c68b
         if (priv) {
e3c68b
             rpc_clnt_connection_cleanup(&priv->rpc->conn);
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
e3c68b
index 052438c..16eefa1 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
e3c68b
@@ -29,6 +29,10 @@ glusterd_conn_init(glusterd_conn_t *conn, char *sockpath, int frame_timeout,
e3c68b
     if (!this)
e3c68b
         goto out;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     svc = glusterd_conn_get_svc_object(conn);
e3c68b
     if (!svc) {
e3c68b
         gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_GET_FAIL,
e3c68b
@@ -36,7 +40,7 @@ glusterd_conn_init(glusterd_conn_t *conn, char *sockpath, int frame_timeout,
e3c68b
         goto out;
e3c68b
     }
e3c68b
 
e3c68b
-    ret = rpc_transport_unix_options_build(&options, sockpath, frame_timeout);
e3c68b
+    ret = rpc_transport_unix_options_build(options, sockpath, frame_timeout);
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
 
e3c68b
@@ -66,6 +70,8 @@ glusterd_conn_init(glusterd_conn_t *conn, char *sockpath, int frame_timeout,
e3c68b
     conn->rpc = rpc;
e3c68b
     conn->notify = notify;
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     if (ret) {
e3c68b
         if (rpc) {
e3c68b
             rpc_clnt_unref(rpc);
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
index 1cb9013..6147995 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
@@ -3493,11 +3493,10 @@ out:
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
-glusterd_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
+glusterd_transport_inet_options_build(dict_t *dict, const char *hostname,
e3c68b
                                       int port, char *af)
e3c68b
 {
e3c68b
     xlator_t *this = NULL;
e3c68b
-    dict_t *dict = NULL;
e3c68b
     int32_t interval = -1;
e3c68b
     int32_t time = -1;
e3c68b
     int32_t timeout = -1;
e3c68b
@@ -3505,14 +3504,14 @@ glusterd_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
 
e3c68b
     this = THIS;
e3c68b
     GF_ASSERT(this);
e3c68b
-    GF_ASSERT(options);
e3c68b
+    GF_ASSERT(dict);
e3c68b
     GF_ASSERT(hostname);
e3c68b
 
e3c68b
     if (!port)
e3c68b
         port = GLUSTERD_DEFAULT_PORT;
e3c68b
 
e3c68b
     /* Build default transport options */
e3c68b
-    ret = rpc_transport_inet_options_build(&dict, hostname, port, af);
e3c68b
+    ret = rpc_transport_inet_options_build(dict, hostname, port, af);
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
 
e3c68b
@@ -3552,7 +3551,6 @@ glusterd_transport_inet_options_build(dict_t **options, const char *hostname,
e3c68b
     if ((interval > 0) || (time > 0))
e3c68b
         ret = rpc_transport_keepalive_options_set(dict, interval, time,
e3c68b
                                                   timeout);
e3c68b
-    *options = dict;
e3c68b
 out:
e3c68b
     gf_msg_debug("glusterd", 0, "Returning %d", ret);
e3c68b
     return ret;
e3c68b
@@ -3572,6 +3570,10 @@ glusterd_friend_rpc_create(xlator_t *this, glusterd_peerinfo_t *peerinfo,
e3c68b
     if (!peerctx)
e3c68b
         goto out;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     if (args)
e3c68b
         peerctx->args = *args;
e3c68b
 
e3c68b
@@ -3586,7 +3588,7 @@ glusterd_friend_rpc_create(xlator_t *this, glusterd_peerinfo_t *peerinfo,
e3c68b
     if (ret)
e3c68b
         gf_log(this->name, GF_LOG_TRACE,
e3c68b
                "option transport.address-family is not set in xlator options");
e3c68b
-    ret = glusterd_transport_inet_options_build(&options, peerinfo->hostname,
e3c68b
+    ret = glusterd_transport_inet_options_build(options, peerinfo->hostname,
e3c68b
                                                 peerinfo->port, af);
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
@@ -3596,6 +3598,7 @@ glusterd_friend_rpc_create(xlator_t *this, glusterd_peerinfo_t *peerinfo,
e3c68b
      * create our RPC endpoint with the same address that the peer would
e3c68b
      * use to reach us.
e3c68b
      */
e3c68b
+
e3c68b
     if (this->options) {
e3c68b
         data = dict_getn(this->options, "transport.socket.bind-address",
e3c68b
                          SLEN("transport.socket.bind-address"));
e3c68b
@@ -3637,6 +3640,9 @@ glusterd_friend_rpc_create(xlator_t *this, glusterd_peerinfo_t *peerinfo,
e3c68b
     peerctx = NULL;
e3c68b
     ret = 0;
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
+
e3c68b
     GF_FREE(peerctx);
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e3c68b
index ed5ded5..cbed9a9 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e3c68b
@@ -391,6 +391,10 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo)
e3c68b
     if (!defrag)
e3c68b
         goto out;
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     GLUSTERD_GET_DEFRAG_SOCK_FILE(sockfile, volinfo);
e3c68b
     /* Check if defrag sockfile exists in the new location
e3c68b
      * in /var/run/ , if it does not try the old location
e3c68b
@@ -420,7 +424,7 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo)
e3c68b
      * default timeout of 30mins used for unreliable network connections is
e3c68b
      * too long for unix domain socket connections.
e3c68b
      */
e3c68b
-    ret = rpc_transport_unix_options_build(&options, sockfile, 600);
e3c68b
+    ret = rpc_transport_unix_options_build(options, sockfile, 600);
e3c68b
     if (ret) {
e3c68b
         gf_msg(THIS->name, GF_LOG_ERROR, 0, GD_MSG_UNIX_OP_BUILD_FAIL,
e3c68b
                "Unix options build failed");
e3c68b
@@ -437,6 +441,8 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo)
e3c68b
     }
e3c68b
     ret = 0;
e3c68b
 out:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
index ef664c2..2dd5f91 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
@@ -1980,7 +1980,11 @@ glusterd_brick_connect(glusterd_volinfo_t *volinfo,
e3c68b
          * The default timeout of 30mins used for unreliable network
e3c68b
          * connections is too long for unix domain socket connections.
e3c68b
          */
e3c68b
-        ret = rpc_transport_unix_options_build(&options, socketpath, 600);
e3c68b
+        options = dict_new();
e3c68b
+        if (!options)
e3c68b
+            goto out;
e3c68b
+
e3c68b
+        ret = rpc_transport_unix_options_build(options, socketpath, 600);
e3c68b
         if (ret)
e3c68b
             goto out;
e3c68b
 
e3c68b
@@ -1999,7 +2003,8 @@ glusterd_brick_connect(glusterd_volinfo_t *volinfo,
e3c68b
         brickinfo->rpc = rpc;
e3c68b
     }
e3c68b
 out:
e3c68b
-
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     gf_msg_debug("glusterd", 0, "Returning %d", ret);
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
e3c68b
index 89afb9c..d4ab630 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd.c
e3c68b
@@ -1111,11 +1111,15 @@ glusterd_init_uds_listener(xlator_t *this)
e3c68b
 
e3c68b
     GF_ASSERT(this);
e3c68b
 
e3c68b
+    options = dict_new();
e3c68b
+    if (!options)
e3c68b
+        goto out;
e3c68b
+
e3c68b
     sock_data = dict_get(this->options, "glusterd-sockfile");
e3c68b
     (void)snprintf(sockfile, sizeof(sockfile), "%s",
e3c68b
                    sock_data ? sock_data->data : DEFAULT_GLUSTERD_SOCKFILE);
e3c68b
 
e3c68b
-    ret = rpcsvc_transport_unix_options_build(&options, sockfile);
e3c68b
+    ret = rpcsvc_transport_unix_options_build(options, sockfile);
e3c68b
     if (ret)
e3c68b
         goto out;
e3c68b
 
e3c68b
diff --git a/xlators/nfs/server/src/acl3.c b/xlators/nfs/server/src/acl3.c
e3c68b
index 0eca45d..2ede24b 100644
e3c68b
--- a/xlators/nfs/server/src/acl3.c
e3c68b
+++ b/xlators/nfs/server/src/acl3.c
e3c68b
@@ -787,9 +787,14 @@ acl3svc_init(xlator_t *nfsx)
e3c68b
         goto err;
e3c68b
     }
e3c68b
 
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
+
e3c68b
     acl3_inited = _gf_true;
e3c68b
     return &acl3prog;
e3c68b
 err:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return NULL;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
e3c68b
index 726dc29..396809c 100644
e3c68b
--- a/xlators/nfs/server/src/mount3.c
e3c68b
+++ b/xlators/nfs/server/src/mount3.c
e3c68b
@@ -4102,8 +4102,13 @@ mnt3svc_init(xlator_t *nfsx)
e3c68b
             gf_msg_debug(GF_MNT, GF_LOG_DEBUG, "Thread creation failed");
e3c68b
         }
e3c68b
     }
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
+
e3c68b
     return &mnt3prog;
e3c68b
 err:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return NULL;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c
e3c68b
index a341ebd..c3c1453 100644
e3c68b
--- a/xlators/nfs/server/src/nlm4.c
e3c68b
+++ b/xlators/nfs/server/src/nlm4.c
e3c68b
@@ -1121,6 +1121,8 @@ nlm4_establish_callback(nfs3_call_state_t *cs, call_frame_t *cbk_frame)
e3c68b
         ret = 0;
e3c68b
 
e3c68b
 err:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     if (ret == -1) {
e3c68b
         if (rpc_clnt)
e3c68b
             rpc_clnt_unref(rpc_clnt);
e3c68b
@@ -2708,8 +2710,13 @@ nlm4svc_init(xlator_t *nfsx)
e3c68b
 
e3c68b
     gf_timer_call_after(nfsx->ctx, timeout, nlm_grace_period_over, NULL);
e3c68b
     nlm4_inited = _gf_true;
e3c68b
+
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return &nlm4prog;
e3c68b
 err:
e3c68b
+    if (options)
e3c68b
+        dict_unref(options);
e3c68b
     return NULL;
e3c68b
 }
e3c68b
 
e3c68b
-- 
e3c68b
1.8.3.1
e3c68b