cb8e9e
From e472b92b2306c37350ca66678d2b642ff510d8b4 Mon Sep 17 00:00:00 2001
cb8e9e
From: Krishnan Parthasarathi <kparthas@redhat.com>
cb8e9e
Date: Fri, 14 Aug 2015 16:01:05 +0530
cb8e9e
Subject: [PATCH 270/279] rpc: add owner xlator argument to rpc_clnt_new
cb8e9e
cb8e9e
        Backport of http://review.gluster.com/11908
cb8e9e
cb8e9e
The @owner argument tells RPC layer the xlator that owns the connection
cb8e9e
and to which xlator THIS needs be set during network notifications like
cb8e9e
CONNECT and DISCONNECT.
cb8e9e
cb8e9e
Code paths that originate from the head of a (volume) graph and use
cb8e9e
STACK_WIND ensure that the RPC local endpoint has the right xlator saved
cb8e9e
in the frame of the call (callback pair). This guarantees that the
cb8e9e
callback is executed in the right xlator context.
cb8e9e
cb8e9e
The client handshake process which includes fetching of brick ports from
cb8e9e
glusterd, setting lk-version on the brick for the session, don't have
cb8e9e
the correct xlator set in their frames. The problem lies with RPC
cb8e9e
notifications. It doesn't have the provision to set THIS with the xlator
cb8e9e
that is registered with the corresponding RPC programs. e.g,
cb8e9e
RPC_CLNT_CONNECT event received by protocol/client doesn't have THIS set
cb8e9e
to its xlator. This implies, call(-callbacks) originating from this
cb8e9e
thread don't have the right xlator set too.
cb8e9e
cb8e9e
The fix would be to save the xlator registered with the RPC connection
cb8e9e
during rpc_clnt_new. e.g, protocol/client's xlator would be saved with
cb8e9e
the RPC connection that it 'owns'. RPC notifications such as CONNECT,
cb8e9e
DISCONNECT, etc inherit THIS from the RPC connection's xlator.
cb8e9e
cb8e9e
BUG: 1235571
cb8e9e
Change-Id: I6138c7f2ffa9a99a15eec020e1f829400b186ce4
cb8e9e
Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/55164
cb8e9e
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
cb8e9e
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
cb8e9e
---
cb8e9e
 api/src/glfs-internal.h                            |    1 -
cb8e9e
 api/src/glfs-mgmt.c                                |    2 +-
cb8e9e
 cli/src/cli-quotad-client.c                        |    2 +-
cb8e9e
 cli/src/cli.c                                      |    2 +-
cb8e9e
 glusterfsd/src/glusterfsd-mgmt.c                   |    2 +-
cb8e9e
 libglusterfs/src/globals.h                         |    1 +
cb8e9e
 rpc/rpc-lib/src/rpc-clnt.c                         |   19 ++++++++++++++++++-
cb8e9e
 rpc/rpc-lib/src/rpc-clnt.h                         |    4 +++-
cb8e9e
 .../features/changelog/src/changelog-rpc-common.c  |    2 +-
cb8e9e
 xlators/features/quota/src/quota-enforcer-client.c |    2 +-
cb8e9e
 .../snapview-server/src/snapview-server-mgmt.c     |    2 +-
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c     |    2 +-
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-handler.c       |    2 +-
cb8e9e
 xlators/nfs/server/src/nlm4.c                      |    2 +-
cb8e9e
 xlators/protocol/client/src/client.c               |    2 +-
cb8e9e
 15 files changed, 33 insertions(+), 14 deletions(-)
cb8e9e
cb8e9e
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
cb8e9e
index 83b4ade..8ff78de 100644
cb8e9e
--- a/api/src/glfs-internal.h
cb8e9e
+++ b/api/src/glfs-internal.h
cb8e9e
@@ -199,7 +199,6 @@ int glfs_first_lookup (xlator_t *subvol);
cb8e9e
 void glfs_process_upcall_event (struct glfs *fs, void *data);
cb8e9e
         GFAPI_PRIVATE(glfs_process_upcall_event, 3.7.0);
cb8e9e
 
cb8e9e
-#define DECLARE_OLD_THIS xlator_t *old_THIS = NULL
cb8e9e
 
cb8e9e
 #define __GLFS_ENTRY_VALIDATE_FS(fs, label)                         \
cb8e9e
 do {                                                                \
cb8e9e
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
cb8e9e
index 2159d67..903b102 100644
cb8e9e
--- a/api/src/glfs-mgmt.c
cb8e9e
+++ b/api/src/glfs-mgmt.c
cb8e9e
@@ -868,7 +868,7 @@ glfs_mgmt_init (struct glfs *fs)
cb8e9e
 	if (ret)
cb8e9e
 		goto out;
cb8e9e
 
cb8e9e
-	rpc = rpc_clnt_new (options, ctx, THIS->name, 8);
cb8e9e
+	rpc = rpc_clnt_new (options, THIS, THIS->name, 8);
cb8e9e
 	if (!rpc) {
cb8e9e
 		ret = -1;
cb8e9e
 		gf_msg (THIS->name, GF_LOG_WARNING, 0,
cb8e9e
diff --git a/cli/src/cli-quotad-client.c b/cli/src/cli-quotad-client.c
cb8e9e
index 7c16519..d3a2312 100644
cb8e9e
--- a/cli/src/cli-quotad-client.c
cb8e9e
+++ b/cli/src/cli-quotad-client.c
cb8e9e
@@ -131,7 +131,7 @@ cli_quotad_clnt_init (xlator_t *this, dict_t *options)
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
-        rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
cb8e9e
+        rpc = rpc_clnt_new (options, this, this->name, 16);
cb8e9e
         if (!rpc)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
diff --git a/cli/src/cli.c b/cli/src/cli.c
cb8e9e
index 525ec4b..851178b 100644
cb8e9e
--- a/cli/src/cli.c
cb8e9e
+++ b/cli/src/cli.c
cb8e9e
@@ -627,7 +627,7 @@ cli_rpc_init (struct cli_state *state)
cb8e9e
                         goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
cb8e9e
+        rpc = rpc_clnt_new (options, this, this->name, 16);
cb8e9e
         if (!rpc)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
cb8e9e
index 1cff44b..aa7ee4f 100644
cb8e9e
--- a/glusterfsd/src/glusterfsd-mgmt.c
cb8e9e
+++ b/glusterfsd/src/glusterfsd-mgmt.c
cb8e9e
@@ -2038,7 +2038,7 @@ glusterfs_mgmt_init (glusterfs_ctx_t *ctx)
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
-        rpc = rpc_clnt_new (options, THIS->ctx, THIS->name, 8);
cb8e9e
+        rpc = rpc_clnt_new (options, THIS, THIS->name, 8);
cb8e9e
         if (!rpc) {
cb8e9e
                 ret = -1;
cb8e9e
                 gf_log (THIS->name, GF_LOG_WARNING, "failed to create rpc clnt");
cb8e9e
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
cb8e9e
index 9aca3c3..9579c45 100644
cb8e9e
--- a/libglusterfs/src/globals.h
cb8e9e
+++ b/libglusterfs/src/globals.h
cb8e9e
@@ -68,6 +68,7 @@
cb8e9e
 
cb8e9e
 /* THIS */
cb8e9e
 #define THIS (*__glusterfs_this_location())
cb8e9e
+#define DECLARE_OLD_THIS        xlator_t *old_THIS = THIS
cb8e9e
 
cb8e9e
 xlator_t **__glusterfs_this_location ();
cb8e9e
 xlator_t *glusterfs_this_get ();
cb8e9e
diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c
cb8e9e
index 5fbe072..1d87866 100644
cb8e9e
--- a/rpc/rpc-lib/src/rpc-clnt.c
cb8e9e
+++ b/rpc/rpc-lib/src/rpc-clnt.c
cb8e9e
@@ -817,6 +817,16 @@ out:
cb8e9e
 static void
cb8e9e
 rpc_clnt_destroy (struct rpc_clnt *rpc);
cb8e9e
 
cb8e9e
+#define RPC_THIS_SAVE(xl) do {                                  \
cb8e9e
+        old_THIS = THIS ;                                       \
cb8e9e
+        if (!old_THIS)                                          \
cb8e9e
+                gf_log_callingfn ("rpc", GF_LOG_CRITICAL,       \
cb8e9e
+                                  "THIS is not initialised.");  \
cb8e9e
+        THIS = xl;                                              \
cb8e9e
+} while (0)
cb8e9e
+
cb8e9e
+#define RPC_THIS_RESTORE        (THIS = old_THIS)
cb8e9e
+
cb8e9e
 int
cb8e9e
 rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
cb8e9e
                  rpc_transport_event_t event, void *data, ...)
cb8e9e
@@ -828,6 +838,7 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
cb8e9e
         rpc_transport_pollin_t *pollin      = NULL;
cb8e9e
         struct timespec         ts          = {0, };
cb8e9e
         void                   *clnt_mydata = NULL;
cb8e9e
+        DECLARE_OLD_THIS;
cb8e9e
 
cb8e9e
         conn = mydata;
cb8e9e
         if (conn == NULL) {
cb8e9e
@@ -837,6 +848,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
cb8e9e
         if (!clnt)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
+        RPC_THIS_SAVE (clnt->owner);
cb8e9e
+
cb8e9e
         switch (event) {
cb8e9e
         case RPC_TRANSPORT_DISCONNECT:
cb8e9e
         {
cb8e9e
@@ -937,6 +950,7 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata,
cb8e9e
         }
cb8e9e
 
cb8e9e
 out:
cb8e9e
+        RPC_THIS_RESTORE;
cb8e9e
         return ret;
cb8e9e
 }
cb8e9e
 
cb8e9e
@@ -1041,11 +1055,13 @@ out:
cb8e9e
 }
cb8e9e
 
cb8e9e
 struct rpc_clnt *
cb8e9e
-rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx, char *name,
cb8e9e
+rpc_clnt_new (dict_t *options, xlator_t *owner, char *name,
cb8e9e
               uint32_t reqpool_size)
cb8e9e
 {
cb8e9e
         int                    ret  = -1;
cb8e9e
         struct rpc_clnt       *rpc  = NULL;
cb8e9e
+        glusterfs_ctx_t       *ctx  = owner->ctx;
cb8e9e
+
cb8e9e
 
cb8e9e
         rpc = GF_CALLOC (1, sizeof (*rpc), gf_common_mt_rpcclnt_t);
cb8e9e
         if (!rpc) {
cb8e9e
@@ -1054,6 +1070,7 @@ rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx, char *name,
cb8e9e
 
cb8e9e
         pthread_mutex_init (&rpc->lock, NULL);
cb8e9e
         rpc->ctx = ctx;
cb8e9e
+        rpc->owner = owner;
cb8e9e
 
cb8e9e
         if (!reqpool_size)
cb8e9e
                 reqpool_size = RPC_CLNT_DEFAULT_REQUEST_COUNT;
cb8e9e
diff --git a/rpc/rpc-lib/src/rpc-clnt.h b/rpc/rpc-lib/src/rpc-clnt.h
cb8e9e
index ee46a9a..6a4bb40 100644
cb8e9e
--- a/rpc/rpc-lib/src/rpc-clnt.h
cb8e9e
+++ b/rpc/rpc-lib/src/rpc-clnt.h
cb8e9e
@@ -188,9 +188,11 @@ typedef struct rpc_clnt {
cb8e9e
         int                   refcount;
cb8e9e
         int                   auth_null;
cb8e9e
         char                  disabled;
cb8e9e
+        xlator_t             *owner;
cb8e9e
 } rpc_clnt_t;
cb8e9e
 
cb8e9e
-struct rpc_clnt *rpc_clnt_new (dict_t *options, glusterfs_ctx_t *ctx,
cb8e9e
+
cb8e9e
+struct rpc_clnt *rpc_clnt_new (dict_t *options, xlator_t *owner,
cb8e9e
                                char *name, uint32_t reqpool_size);
cb8e9e
 
cb8e9e
 int rpc_clnt_start (struct rpc_clnt *rpc);
cb8e9e
diff --git a/xlators/features/changelog/src/changelog-rpc-common.c b/xlators/features/changelog/src/changelog-rpc-common.c
cb8e9e
index de3a730..b3b14fa 100644
cb8e9e
--- a/xlators/features/changelog/src/changelog-rpc-common.c
cb8e9e
+++ b/xlators/features/changelog/src/changelog-rpc-common.c
cb8e9e
@@ -52,7 +52,7 @@ changelog_rpc_client_init (xlator_t *this, void *cbkdata,
cb8e9e
                 goto dealloc_dict;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
cb8e9e
+        rpc = rpc_clnt_new (options, this, this->name, 16);
cb8e9e
         if (!rpc)
cb8e9e
                 goto dealloc_dict;
cb8e9e
 
cb8e9e
diff --git a/xlators/features/quota/src/quota-enforcer-client.c b/xlators/features/quota/src/quota-enforcer-client.c
cb8e9e
index 067db6d..10bd24f 100644
cb8e9e
--- a/xlators/features/quota/src/quota-enforcer-client.c
cb8e9e
+++ b/xlators/features/quota/src/quota-enforcer-client.c
cb8e9e
@@ -453,7 +453,7 @@ quota_enforcer_init (xlator_t *this, dict_t *options)
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
-        rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
cb8e9e
+        rpc = rpc_clnt_new (options, this, this->name, 16);
cb8e9e
         if (!rpc) {
cb8e9e
                 ret = -1;
cb8e9e
                 goto out;
cb8e9e
diff --git a/xlators/features/snapview-server/src/snapview-server-mgmt.c b/xlators/features/snapview-server/src/snapview-server-mgmt.c
cb8e9e
index 0fe3687..4b61326 100644
cb8e9e
--- a/xlators/features/snapview-server/src/snapview-server-mgmt.c
cb8e9e
+++ b/xlators/features/snapview-server/src/snapview-server-mgmt.c
cb8e9e
@@ -85,7 +85,7 @@ svs_mgmt_init (xlator_t *this)
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        priv->rpc = rpc_clnt_new (options, this->ctx, this->name, 8);
cb8e9e
+        priv->rpc = rpc_clnt_new (options, this, this->name, 8);
cb8e9e
         if (!priv->rpc) {
cb8e9e
                 gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC");
cb8e9e
                 goto out;
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
cb8e9e
index fca9323..607a065 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c
cb8e9e
@@ -46,7 +46,7 @@ glusterd_conn_init (glusterd_conn_t *conn, char *sockpath,
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
         /* @options is free'd by rpc_transport when destroyed */
cb8e9e
-        rpc = rpc_clnt_new (options, this->ctx, (char *)svc->name, 16);
cb8e9e
+        rpc = rpc_clnt_new (options, this, (char *)svc->name, 16);
cb8e9e
         if (!rpc) {
cb8e9e
                 ret = -1;
cb8e9e
                 goto out;
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
cb8e9e
index 82bd7b1..ed5d6ff 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
cb8e9e
@@ -3295,7 +3295,7 @@ glusterd_rpc_create (struct rpc_clnt **rpc,
cb8e9e
         GF_ASSERT (options);
cb8e9e
 
cb8e9e
         /* TODO: is 32 enough? or more ? */
cb8e9e
-        new_rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
cb8e9e
+        new_rpc = rpc_clnt_new (options, this, this->name, 16);
cb8e9e
         if (!new_rpc)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c
cb8e9e
index a1127a3..ac45b4f 100644
cb8e9e
--- a/xlators/nfs/server/src/nlm4.c
cb8e9e
+++ b/xlators/nfs/server/src/nlm4.c
cb8e9e
@@ -1055,7 +1055,7 @@ nlm4_establish_callback (void *csarg)
cb8e9e
         }
cb8e9e
 
cb8e9e
         /* TODO: is 32 frames in transit enough ? */
cb8e9e
-        rpc_clnt = rpc_clnt_new (options, cs->nfsx->ctx, "NLM-client", 32);
cb8e9e
+        rpc_clnt = rpc_clnt_new (options, cs->nfsx, "NLM-client", 32);
cb8e9e
         if (rpc_clnt == NULL) {
cb8e9e
                 gf_msg (GF_NLM, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
cb8e9e
                         "rpc_clnt NULL");
cb8e9e
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
cb8e9e
index db7a07a..ccb26dd 100644
cb8e9e
--- a/xlators/protocol/client/src/client.c
cb8e9e
+++ b/xlators/protocol/client/src/client.c
cb8e9e
@@ -2286,7 +2286,7 @@ client_init_rpc (xlator_t *this)
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name, 0);
cb8e9e
+        conf->rpc = rpc_clnt_new (this->options, this, this->name, 0);
cb8e9e
         if (!conf->rpc) {
cb8e9e
                 gf_msg (this->name, GF_LOG_ERROR, 0, PC_MSG_RPC_INIT_FAILED,
cb8e9e
                         "failed to initialize RPC");
cb8e9e
-- 
cb8e9e
1.7.1
cb8e9e