From dcebed550ebfc878b0b3bd02ab7fe15db6764f81 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Mon, 15 Apr 2013 22:07:21 +0530 Subject: glusterd: Avoided deadlock in single node cluster, glusterd restart In a single node cluster, it is possible to deadlock on the "big lock", while restarting bricks. In glusterd_restart_bricks, we perform a glusterd_brick_connect, where we release the big lock in anticipation that glusterd_brick_rpc_notify could run in the same C stack (and deadlocking). So, in the restart code path, we could unlock before we have performed a lock on the big lock. To fix this, we need to take the big lock in the glusterd_launch_synctask 'thread' as well. Change-Id: I1abea1ca82b55c784b8a810a8194f254b32b1dcc BUG: 948686 Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.org/4837 Tested-by: Gluster Build System Reviewed-by: Jeff Darcy --- xlators/mgmt/glusterd/src/glusterd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'xlators/mgmt/glusterd/src/glusterd.c') diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index cb5daf4bb..41a1cb368 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -873,6 +873,8 @@ _install_mount_spec (dict_t *opts, char *key, data_t *value, void *data) static int gd_default_synctask_cbk (int ret, call_frame_t *frame, void *opaque) { + glusterd_conf_t *priv = THIS->private; + synclock_unlock (&priv->big_lock); return ret; } @@ -886,6 +888,7 @@ glusterd_launch_synctask (synctask_fn_t fn, void *opaque) this = THIS; priv = this->private; + synclock_lock (&priv->big_lock); ret = synctask_new (this->ctx->env, fn, gd_default_synctask_cbk, NULL, opaque); if (ret) -- cgit