summaryrefslogtreecommitdiffstats
path: root/rpc
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kparthas@redhat.com>2015-02-25 15:49:11 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-02-27 21:16:11 -0800
commitb117d4d84becd25ef79c049ebf9b8ec6c4abca88 (patch)
tree3e989a4fc35b10a6179d63032960be9bfe10d657 /rpc
parenta0f30e637e6ee32b113fd21268be17e0618d39df (diff)
downloadglusterfs-b117d4d84becd25ef79c049ebf9b8ec6c4abca88.tar.gz
glusterfs-b117d4d84becd25ef79c049ebf9b8ec6c4abca88.tar.xz
glusterfs-b117d4d84becd25ef79c049ebf9b8ec6c4abca88.zip
socket: allow only one epoll thread to read msg fragments
__socket_read_reply function releases sock priv->lock briefly for notifying higher layers of message's xid. This could result in other epoll threads that are processing events on this socket to read further fragments of the same message. This may lead to incorrect fragment processing and result in a crash. Change-Id: I915665b2e54ca16f2ad65970e51bf76c65d954a4 BUG: 1197118 Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com> Signed-off-by: Shyam <srangana@redhat.com> Reviewed-on: http://review.gluster.org/9742 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Tested-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'rpc')
-rw-r--r--rpc/rpc-transport/socket/src/socket.c12
-rw-r--r--rpc/rpc-transport/socket/src/socket.h1
2 files changed, 13 insertions, 0 deletions
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
index 0a3a5812a9..a7e2bb0cfd 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -1904,6 +1904,7 @@ __socket_read_reply (rpc_transport_t *this)
/* release priv->lock, so as to avoid deadlock b/w conn->lock
* and priv->lock, since we are doing an upcall here.
*/
+ frag->state = SP_STATE_NOTIFYING_XID;
pthread_mutex_unlock (&priv->lock);
{
ret = rpc_transport_notify (this,
@@ -1912,6 +1913,9 @@ __socket_read_reply (rpc_transport_t *this)
}
pthread_mutex_lock (&priv->lock);
+ /* Transition back to externally visible state. */
+ frag->state = SP_STATE_READ_MSGTYPE;
+
if (ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
"notify for event MAP_XID failed for %s",
@@ -1999,6 +2003,14 @@ __socket_read_frag (rpc_transport_t *this)
}
break;
+
+ case SP_STATE_NOTIFYING_XID:
+ /* Another epoll thread is notifying higher layers
+ *of reply's xid. */
+ errno = EAGAIN;
+ return -1;
+ break;
+
}
out:
diff --git a/rpc/rpc-transport/socket/src/socket.h b/rpc/rpc-transport/socket/src/socket.h
index 33c936938e..6a8ab870ab 100644
--- a/rpc/rpc-transport/socket/src/socket.h
+++ b/rpc/rpc-transport/socket/src/socket.h
@@ -59,6 +59,7 @@ typedef enum {
SP_STATE_RPCFRAG_INIT,
SP_STATE_READING_MSGTYPE,
SP_STATE_READ_MSGTYPE,
+ SP_STATE_NOTIFYING_XID
} sp_rpcfrag_state_t;
typedef enum {