summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c1
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h1
-rw-r--r--xlators/protocol/server/src/server.c17
3 files changed, 19 insertions, 0 deletions
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index e6421fcfab5..f9cbdf133c7 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -365,6 +365,7 @@ rpc_transport_load(glusterfs_ctx_t *ctx, dict_t *options, char *trans_name)
}
INIT_LIST_HEAD(&trans->list);
+ GF_ATOMIC_INIT(trans->disconnect_progress, 0);
return_trans = trans;
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
index 7be1ba14a0c..9e75d1a2bbb 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -214,6 +214,7 @@ struct rpc_transport {
gf_boolean_t connect_failed;
char notify_poller_death;
char poller_death_accept;
+ gf_atomic_t disconnect_progress;
};
struct rpc_transport_ops {
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index 50c6c30d63f..8b89e18d156 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -475,6 +475,10 @@ server_rpc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, void *data)
break;
}
+ /* Set the disconnect_progress flag to 1 to avoid races
+ during brick detach while brick mux is enabled
+ */
+ GF_ATOMIC_INIT(trans->disconnect_progress, 1);
/* transport has to be removed from the list upon disconnect
* irrespective of whether lock self heal is off or on, since
* new transport will be created upon reconnect.
@@ -1536,6 +1540,7 @@ server_notify(xlator_t *this, int32_t event, void *data, ...)
glusterfs_ctx_t *ctx = NULL;
gf_boolean_t xprt_found = _gf_false;
uint64_t totxprt = 0;
+ uint64_t totdisconnect = 0;
GF_VALIDATE_OR_GOTO(THIS->name, this, out);
conf = this->private;
@@ -1609,6 +1614,10 @@ server_notify(xlator_t *this, int32_t event, void *data, ...)
if (!xprt->xl_private) {
continue;
}
+
+ if (GF_ATOMIC_GET(xprt->disconnect_progress))
+ continue;
+
if (xprt->xl_private->bound_xl == data) {
totxprt++;
}
@@ -1635,14 +1644,22 @@ server_notify(xlator_t *this, int32_t event, void *data, ...)
if (!xprt->xl_private) {
continue;
}
+
+ if (GF_ATOMIC_GET(xprt->disconnect_progress))
+ continue;
+
if (xprt->xl_private->bound_xl == data) {
gf_log(this->name, GF_LOG_INFO, "disconnecting %s",
xprt->peerinfo.identifier);
xprt_found = _gf_true;
+ totdisconnect++;
rpc_transport_disconnect(xprt, _gf_false);
}
}
+ if (totxprt > totdisconnect)
+ GF_ATOMIC_SUB(victim->xprtrefcnt, (totxprt - totdisconnect));
+
pthread_mutex_unlock(&conf->mutex);
if (this->ctx->active) {
top = this->ctx->active->first;