summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kp@gluster.com>2012-01-11 15:39:38 +0530
committerVijay Bellur <vijay@gluster.com>2012-02-03 07:40:46 -0800
commit3ec7680a70bcace6b195ae412362b7e1b072eaeb (patch)
tree3b67cb58722f5a9ed3abca98c011e654c649b359
parent2313600f0749094f1246e663a0db15da3c2812db (diff)
glusterd: Changed op_sm_queue locking mechanism to accomodate nested calls to op_sm
Today if an rpc call made inside an op_sm can fail due to a disconnected peer, resulting in the rpc callback to be called in the same stack with appropriate status set. All glusterd rpc cbks move the state machine based on the status returned by the rpc layer, which would result in a nested call to op_sm. With the current scheme of locking, glusterd would end up in a deadlock situation The new scheme will fail the nested glusterd_op_sm (). This prevents the deadlock. It would work without any change in overall behaviour, as the current op_sm () call in execution wouldn't return until all events in the queue are processed. Change-Id: I6a7ba16d3810b699bcd06dc28a5ff3205a25476f BUG: 772142 Signed-off-by: Krishnan Parthasarathi <kp@gluster.com> Reviewed-on: http://review.gluster.com/2625 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amar@gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index f24cb9b13..d0d280a09 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -3570,11 +3570,16 @@ glusterd_op_sm ()
glusterd_op_sm_event_t *event = NULL;
glusterd_op_sm_event_t *tmp = NULL;
int ret = -1;
+ int lock_err = 0;
glusterd_op_sm_ac_fn handler = NULL;
glusterd_op_sm_t *state = NULL;
glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- (void ) pthread_mutex_lock (&gd_op_sm_lock);
+ if ((lock_err = pthread_mutex_trylock (&gd_op_sm_lock))) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "lock failed due to %s",
+ strerror (lock_err));
+ goto lock_failed;
+ }
while (!list_empty (&gd_op_sm_queue)) {
@@ -3624,6 +3629,8 @@ glusterd_op_sm ()
(void ) pthread_mutex_unlock (&gd_op_sm_lock);
ret = 0;
+lock_failed:
+
return ret;
}