summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2013-12-09 16:10:56 +0530
committerAnand Avati <avati@redhat.com>2013-12-10 09:30:26 -0800
commitc492b2cf8a18f09975da24e60330d0454cbd1e4e (patch)
treef02ceab70deac11fbc4106666afe2e352f1745fc
parent980fb894798240076142ea74b0d49dd2b4160462 (diff)
mount/fuse: cleanup old graphs.
After a graph switch, a PARENT_DOWN event from fuse indicates protocol/client to shutdown all its sockets. However, this event will be sent only when the first fop is received from fuse mount after graph switch. Also, this event is sent only on previously active graph. So, if there are multiple graph switches when there is no activity on mountpoint, we'll be left with a list of graphs with their sockets still open. This patch fixes the issue by sending PARENT_DOWN to previously non-active graph when a new graph is available irrespective of whether there is an activity on mount-point. Change-Id: I9e676658d797c0b2dd3ed5ca5a56271bd94b4bb6 BUG: 924726 Signed-off-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-on: http://review.gluster.org/4713 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-rwxr-xr-xtests/bugs/bug-924726.t45
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c30
2 files changed, 69 insertions, 6 deletions
diff --git a/tests/bugs/bug-924726.t b/tests/bugs/bug-924726.t
new file mode 100755
index 00000000000..82c11af878e
--- /dev/null
+++ b/tests/bugs/bug-924726.t
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+TESTS_EXPECTED_IN_LOOP=10
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+function get_socket_count() {
+ netstat -nap | grep $1 | wc -l
+}
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume info;
+
+TEST $CLI volume create $V0 $H0:$B0/$V0
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+TEST glusterfs -s $H0 --volfile-id $V0 $M0;
+
+TEST ls $M0
+
+GLFS_MNT_PID=`ps ax | grep -i $M0 | grep glusterfs | grep -v grep | sed -e "s/^ *\([0-9]*\).*/\1/g"`
+
+SOCKETS_BEFORE_SWITCH=`netstat -nap | grep $GLFS_MNT_PID | grep ESTABLISHED | wc -l`
+
+for i in $(seq 1 5); do
+ TEST_IN_LOOP $CLI volume set $V0 performance.write-behind off;
+ sleep 1;
+ TEST_IN_LOOP $CLI volume set $V0 performance.write-behind on;
+ sleep 1;
+done
+
+SOCKETS_AFTER_SWITCH=`netstat -nap | grep $GLFS_MNT_PID | grep ESTABLISHED | wc -l`
+
+# currently active graph is not cleaned up till some operation on
+# mount-point. Hence there is one extra graph.
+TEST [ $SOCKETS_AFTER_SWITCH = `expr $SOCKETS_BEFORE_SWITCH + 1` ]
+
+cleanup;
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 96c745a09c3..ecfe86d5d34 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -4906,9 +4906,10 @@ dump_history_fuse (circular_buffer_t *cb, void *data)
int
fuse_graph_setup (xlator_t *this, glusterfs_graph_t *graph)
{
- inode_table_t *itable = NULL;
- int ret = 0;
- fuse_private_t *priv = NULL;
+ inode_table_t *itable = NULL;
+ int ret = 0, winds = 0;
+ fuse_private_t *priv = NULL;
+ glusterfs_graph_t *prev_graph = NULL;
priv = this->private;
@@ -4929,13 +4930,30 @@ fuse_graph_setup (xlator_t *this, glusterfs_graph_t *graph)
pthread_mutex_lock (&priv->sync_mutex);
{
- priv->next_graph = graph;
- priv->event_recvd = 0;
+ prev_graph = priv->next_graph;
+
+ if ((prev_graph != NULL) && (prev_graph->id > graph->id)) {
+ /* there was a race and an old graph was initialised
+ * before new one.
+ */
+ prev_graph = graph;
+ } else {
+ priv->next_graph = graph;
+ priv->event_recvd = 0;
- pthread_cond_signal (&priv->sync_cond);
+ pthread_cond_signal (&priv->sync_cond);
+ }
+
+ if (prev_graph != NULL)
+ winds = ((xlator_t *)prev_graph->top)->winds;
}
pthread_mutex_unlock (&priv->sync_mutex);
+ if ((prev_graph != NULL) && (winds == 0)) {
+ xlator_notify (prev_graph->top, GF_EVENT_PARENT_DOWN,
+ prev_graph->top, NULL);
+ }
+
gf_log ("fuse", GF_LOG_INFO, "switched to graph %d",
((graph) ? graph->id : 0));