diff options
author | Mohammed Rafi KC <rkavunga@redhat.com> | 2014-10-13 11:12:14 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2014-11-14 04:03:59 -0800 |
commit | f645655c65d1f9787a82a5dcbb0e24e2d32bed87 (patch) | |
tree | 51ceb9d76cbbf81e1f02ccdd64f9454c6aa94937 /rpc | |
parent | c3c28ad86be6feb0b148df4681da432047dc0bc3 (diff) |
rdma: glusterd crash if rdma_disconnect is called as soon as connect a request.
we are initializing connection in server side immediately after
rdma_accept is called. But we are delaying adding the transport
to listener list until getting RDMA_CM_EVENT_ESTABLISHED event.
Before getting this event if disconnect is called glusterd will
try to remove the transport from list which is not added. So if
the list is empty it causes a glusterd crash . In this patch we
will call the function to initialize the connection as soon as
rdma_accept is called.
Change-Id: I019480297a85349ede3101ee9c7c1596dc5c73e2
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
BUG: 1164079
Reviewed-on: http://review.gluster.org/8925
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Tested-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'rpc')
-rw-r--r-- | rpc/rpc-transport/rdma/src/rdma.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/rpc/rpc-transport/rdma/src/rdma.c b/rpc/rpc-transport/rdma/src/rdma.c index 4c01c14a927..3ceb197f2a3 100644 --- a/rpc/rpc-transport/rdma/src/rdma.c +++ b/rpc/rpc-transport/rdma/src/rdma.c @@ -58,6 +58,8 @@ gf_rdma_disconnect (rpc_transport_t *this); static void gf_rdma_cm_handle_disconnect (rpc_transport_t *this); +static int +gf_rdma_cm_handle_connect_init (struct rdma_cm_event *event); static void gf_rdma_put_post (gf_rdma_queue_t *queue, gf_rdma_post_t *post) @@ -785,7 +787,7 @@ gf_rdma_cm_handle_connect_request (struct rdma_cm_event *event) rpc_transport_t *this = NULL, *listener = NULL; struct rdma_cm_id *child_cm_id = NULL, *listener_cm_id = NULL; struct rdma_conn_param conn_param = {0, }; - gf_rdma_private_t *priv = NULL, *child_priv = NULL; + gf_rdma_private_t *priv = NULL; gf_rdma_options_t *options = NULL; child_cm_id = event->id; @@ -804,7 +806,7 @@ gf_rdma_cm_handle_connect_request (struct rdma_cm_event *event) rdma_destroy_id (child_cm_id); goto out; } - child_priv = this->private; + gf_log (listener->name, GF_LOG_TRACE, "got a connect request (me:%s peer:%s)", listener->myinfo.identifier, this->peerinfo.identifier); @@ -831,7 +833,7 @@ gf_rdma_cm_handle_connect_request (struct rdma_cm_event *event) gf_rdma_cm_handle_disconnect (this); goto out; } - child_priv->connected = 1; + gf_rdma_cm_handle_connect_init (event); ret = 0; out: @@ -965,7 +967,7 @@ gf_rdma_cm_handle_disconnect (rpc_transport_t *this) static int -gf_rdma_cm_handle_event_established (struct rdma_cm_event *event) +gf_rdma_cm_handle_connect_init (struct rdma_cm_event *event) { rpc_transport_t *this = NULL; gf_rdma_private_t *priv = NULL; @@ -976,6 +978,13 @@ gf_rdma_cm_handle_event_established (struct rdma_cm_event *event) this = cm_id->context; priv = this->private; + if (priv->connected == 1) { + gf_log (this->name, GF_LOG_TRACE, + "received event RDMA_CM_EVENT_ESTABLISHED (me:%s peer:%s)", + this->myinfo.identifier, this->peerinfo.identifier); + return ret; + } + priv->connected = 1; pthread_mutex_lock (&priv->write_mutex); @@ -986,6 +995,9 @@ gf_rdma_cm_handle_event_established (struct rdma_cm_event *event) pthread_mutex_unlock (&priv->write_mutex); if (priv->entity == GF_RDMA_CLIENT) { + gf_log (this->name, GF_LOG_TRACE, + "received event RDMA_CM_EVENT_ESTABLISHED (me:%s peer:%s)", + this->myinfo.identifier, this->peerinfo.identifier); ret = rpc_transport_notify (this, RPC_TRANSPORT_CONNECT, this); } else if (priv->entity == GF_RDMA_SERVER) { @@ -997,10 +1009,6 @@ gf_rdma_cm_handle_event_established (struct rdma_cm_event *event) gf_rdma_disconnect (this); } - gf_log (this->name, GF_LOG_TRACE, - "received event RDMA_CM_EVENT_ESTABLISHED (me:%s peer:%s)", - this->myinfo.identifier, this->peerinfo.identifier); - return ret; } @@ -1060,7 +1068,7 @@ gf_rdma_cm_event_handler (void *data) break; case RDMA_CM_EVENT_ESTABLISHED: - gf_rdma_cm_handle_event_established (event); + gf_rdma_cm_handle_connect_init (event); break; case RDMA_CM_EVENT_ADDR_ERROR: |