diff options
author | Krishnan Parthasarathi <kparthas@redhat.com> | 2013-04-02 07:56:25 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-04-12 13:47:46 -0700 |
commit | f34343d3751cd73e8eabe6d5544fb1f58b316595 (patch) | |
tree | 869aa908771b3708f4ad9a7a7ec57a623239b9a5 /tests/bugs | |
parent | 732cd267c924554a638519cff0df146b2688d6e8 (diff) |
glusterd: big lock - a coarse-grained locking to prevent races
There are primarily three lists that are part of glusterd process,
that are concurrently accessed. Namely, priv->volumes, priv->peers
and volinfo->bricks_list.
Big-lock approach
-----------------
WHAT IS IT?
Big lock is a coarse-grained lock which protects all three
lists, mentioned above, from racy access.
HOW DOES IT WORK?
At any given point in time, glusterd's thread(s) are in execution
_iff_ there is a preceding, inbound network event. Of course, the
sigwaiter thread and timer thread are exceptions.
A network event is an external trigger to glusterd, via the epoll
thread, in the form of POLLIN and POLLERR.
As long as we take the big-lock at all such entry points and yield
it when we are done, we are guaranteed that all the network events,
accessing the global lists, are serialised.
This amounts to holding the big lock at
- all the handlers of all the actors in glusterd. (POLLIN)
- all the cbks in glusterd. (POLLIN)
- rpc_notify (DISCONNECT event), if we access/modify
one of the three lists. (POLLERR)
In the case of synctask'ized volume operations, we must remember that,
if we held the big lock for the entire duration of the handler,
we may block other non-synctask rpc actors from executing.
For eg, volume-start would block in PMAP SIGNIN, if done incorrectly.
To prevent this, we need to yield the big lock, when we yield the
synctask, and reacquire on waking up of the synctask.
Change-Id: Ib929f9905b55fb6c3fc27fefb497a26dba058e4f
BUG: 948686
Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com>
Reviewed-on: http://review.gluster.org/4784
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'tests/bugs')
-rw-r--r-- | tests/bugs/bug-948686.t | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/tests/bugs/bug-948686.t b/tests/bugs/bug-948686.t new file mode 100644 index 00000000000..63c099a79bc --- /dev/null +++ b/tests/bugs/bug-948686.t @@ -0,0 +1,36 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../cluster.rc + +function check_peers { + $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l +} +cleanup; +#setup cluster and test volume +TEST launch_cluster 3; # start 3-node virtual cluster +TEST $CLI_1 peer probe $H2; # peer probe server 2 from server 1 cli +TEST $CLI_1 peer probe $H3; # peer probe server 3 from server 1 cli + +EXPECT_WITHIN 20 2 check_peers; + +TEST $CLI_1 volume create $V0 replica 2 $H1:$B1/$V0 $H1:$B1/${V0}_1 $H2:$B2/$V0 $H3:$B3/$V0 +TEST $CLI_1 volume start $V0 +TEST glusterfs --volfile-server=$H1 --volfile-id=$V0 $M0 + +#kill a node +TEST kill_node 3 + +#modify volume config to see change in volume-sync +TEST $CLI_1 volume set $V0 write-behind off +#add some files to the volume to see effect of volume-heal cmd +TEST touch $M0/{1..100}; +TEST $CLI_1 volume stop $V0; +TEST $glusterd_3; +sleep 3; +TEST $CLI_3 volume start $V0; +TEST $CLI_2 volume stop $V0; +TEST $CLI_2 volume delete $V0; + +cleanup; |