e7a346
From f58abec63fb325e0e1c21fe3fe127de2e4a85d7d Mon Sep 17 00:00:00 2001
e7a346
From: Mohit Agrawal <moagrawa@redhat.com>
e7a346
Date: Thu, 24 Jan 2019 18:45:54 +0530
e7a346
Subject: [PATCH 509/510] core: heketi-cli is throwing error "target is busy"
e7a346
e7a346
Problem: At the time of deleting block hosting volume
e7a346
         through heketi-cli , it is throwing an error "target is busy".
e7a346
         cli is throwing an error because brick is not detached successfully
e7a346
         and brick is not detached due to race condition to cleanp xprt
e7a346
         associated with detached brick
e7a346
e7a346
Solution: To avoid xprt specifc race condition introduce an atomic flag
e7a346
          on rpc_transport
e7a346
e7a346
> Change-Id: Id4ff1fe8375a63be71fb3343f455190a1b8bb6d4
e7a346
> fixes: bz#1668190
e7a346
> (Cherry pick from commit 04f84756e1baa5eff4560339700f82970eaa5d80)
e7a346
> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/22073/)
e7a346
e7a346
Change-Id: Ie3786b569ee03569bc3ac970925732dd834a76dc
e7a346
BUG: 1669020
e7a346
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/161388
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
e7a346
---
e7a346
 rpc/rpc-lib/src/rpc-transport.c      |  1 +
e7a346
 rpc/rpc-lib/src/rpc-transport.h      |  1 +
e7a346
 xlators/protocol/server/src/server.c | 18 ++++++++++++++++++
e7a346
 3 files changed, 20 insertions(+)
e7a346
e7a346
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
e7a346
index 77abf9617..0c6ab6694 100644
e7a346
--- a/rpc/rpc-lib/src/rpc-transport.c
e7a346
+++ b/rpc/rpc-lib/src/rpc-transport.c
e7a346
@@ -371,6 +371,7 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
e7a346
 	}
e7a346
 
e7a346
         INIT_LIST_HEAD (&trans->list);
e7a346
+        GF_ATOMIC_INIT(trans->disconnect_progress, 0);
e7a346
 
e7a346
         return_trans = trans;
e7a346
 
e7a346
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
e7a346
index 23246c564..f5fb6e13b 100644
e7a346
--- a/rpc/rpc-lib/src/rpc-transport.h
e7a346
+++ b/rpc/rpc-lib/src/rpc-transport.h
e7a346
@@ -217,6 +217,7 @@ struct rpc_transport {
e7a346
          * layer or in client management notification handler functions
e7a346
          */
e7a346
         gf_boolean_t               connect_failed;
e7a346
+        gf_atomic_t                disconnect_progress;
e7a346
 };
e7a346
 
e7a346
 struct rpc_transport_ops {
e7a346
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
e7a346
index 104615265..ba3b8316d 100644
e7a346
--- a/xlators/protocol/server/src/server.c
e7a346
+++ b/xlators/protocol/server/src/server.c
e7a346
@@ -553,6 +553,11 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
e7a346
                         break;
e7a346
                 }
e7a346
 
e7a346
+                /* Set the disconnect_progress flag to 1 to avoid races
e7a346
+                   during brick detach while brick mux is enabled
e7a346
+                */
e7a346
+                GF_ATOMIC_INIT(trans->disconnect_progress, 1);
e7a346
+
e7a346
                 /* transport has to be removed from the list upon disconnect
e7a346
                  * irrespective of whether lock self heal is off or on, since
e7a346
                  * new transport will be created upon reconnect.
e7a346
@@ -1638,6 +1643,7 @@ notify (xlator_t *this, int32_t event, void *data, ...)
e7a346
         glusterfs_ctx_t  *ctx         = NULL;
e7a346
         gf_boolean_t     xprt_found   = _gf_false;
e7a346
         uint64_t         totxprt      = 0;
e7a346
+        uint64_t         totdisconnect = 0;
e7a346
 
e7a346
         GF_VALIDATE_OR_GOTO (THIS->name, this, out);
e7a346
         conf = this->private;
e7a346
@@ -1715,6 +1721,10 @@ notify (xlator_t *this, int32_t event, void *data, ...)
e7a346
                         if (!xprt->xl_private) {
e7a346
                                 continue;
e7a346
                         }
e7a346
+
e7a346
+                        if (GF_ATOMIC_GET(xprt->disconnect_progress))
e7a346
+                                continue;
e7a346
+
e7a346
                         if (xprt->xl_private->bound_xl == data) {
e7a346
                                 totxprt++;
e7a346
                         }
e7a346
@@ -1740,15 +1750,23 @@ notify (xlator_t *this, int32_t event, void *data, ...)
e7a346
                         if (!xprt->xl_private) {
e7a346
                                 continue;
e7a346
                         }
e7a346
+
e7a346
+                        if (GF_ATOMIC_GET(xprt->disconnect_progress))
e7a346
+                                continue;
e7a346
+
e7a346
                         if (xprt->xl_private->bound_xl == data) {
e7a346
                                 gf_log (this->name, GF_LOG_INFO,
e7a346
                                         "disconnecting %s",
e7a346
                                         xprt->peerinfo.identifier);
e7a346
                                 xprt_found = _gf_true;
e7a346
+                                totdisconnect++;
e7a346
                                 rpc_transport_disconnect (xprt, _gf_false);
e7a346
                         }
e7a346
                 }
e7a346
 
e7a346
+                if (totxprt > totdisconnect)
e7a346
+                        GF_ATOMIC_SUB(victim->xprtrefcnt, (totxprt - totdisconnect));
e7a346
+
e7a346
                 pthread_mutex_unlock (&conf->mutex);
e7a346
                 if (this->ctx->active) {
e7a346
                         top = this->ctx->active->first;
e7a346
-- 
e7a346
2.20.1
e7a346