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