summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuradha Talur <atalur@redhat.com>2016-05-13 15:34:06 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2016-05-13 22:39:24 -0700
commit53d16409f933110da11338ef26d1fa7b2e921cec (patch)
tree46992fad6bb583b4e0d610a7716759d8c0fa0709
parent48608e2ca1c6d681c0c60c71ae41b403554bb71d (diff)
cluster/afr : Do post-op in case of symmetric errors
In afr_changelog_post_op_now(), if there was any error, meaning op_ret < 0, post-op was not being done even when the errors were symmetric and there were no "failed subvols". Fix: When the errors are symmetric, perform post-op. How was the bug found : In a 1 X 3 volume with shard and write behind on when writes were done into a file with one brick down, the trusted.afr.dirty xattr's value for .shard directory would keep increasing as post op was not done but pre-op was. This incorrectly showed .shard to be in split-brain. RCA: When WB is on, due to multiple writes being sent on offset lying in the same shard, chances are that same shard file will be created more than once with the second one failing with op_ret < 0 and op_errno = EEXIST. As op_ret was negative, afr wouldn't do post-op, leading to no decrement of trusted.afr.dirty xattr. Thus showing .shard directory to be in split-brain. Change-Id: I711bdeaa1397244e6a7790e96f0c84501798fc59 BUG: 1335652 Signed-off-by: Anuradha Talur <atalur@redhat.com> Reviewed-on: http://review.gluster.org/14310 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Ravishankar N <ravishankar@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r--tests/bugs/replicate/bug-1335652.t29
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c8
2 files changed, 35 insertions, 2 deletions
diff --git a/tests/bugs/replicate/bug-1335652.t b/tests/bugs/replicate/bug-1335652.t
new file mode 100644
index 00000000000..653a1b05ce2
--- /dev/null
+++ b/tests/bugs/replicate/bug-1335652.t
@@ -0,0 +1,29 @@
+#!/bin/bash
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
+TEST $CLI volume set $V0 shard on
+TEST $CLI volume set $V0 self-heal-daemon off
+TEST $CLI volume set $V0 data-self-heal off
+TEST $CLI volume set $V0 entry-self-heal off
+TEST $CLI volume set $V0 metadata-self-heal off
+TEST $CLI volume start $V0
+
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
+
+#Kill the zero'th brick so that 1st and 2nd get marked dirty
+TEST kill_brick $V0 $H0 $B0/${V0}0
+
+TEST dd if=/dev/urandom of=$M0/file bs=10MB count=20
+
+#At any point value of dirty should not be greater than 0 on source bricks
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.dirty $B0/${V0}1/.shard
+EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.dirty $B0/${V0}2/.shard
+
+rm -rf $M0/file;
+
+cleanup;
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 6fd44ce79f6..ef5cb56279f 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -586,10 +586,14 @@ afr_handle_symmetric_errors (call_frame_t *frame, xlator_t *this)
}
i_errno = local->replies[i].op_errno;
- if (i_errno == ENOTCONN) {
+ if (i_errno == ENOTCONN || i_errno == EDQUOT ||
+ i_errno == ENOSPC) {
/* ENOTCONN is not a symmetric error. We do not
know if the operation was performed on the
backend or not.
+ * Before reaching EDQUOT and ENOSPC, each brick would
+ * have written some amount of data, hence this is not
+ * symmetric error.
*/
matching_errors = _gf_false;
break;
@@ -766,7 +770,7 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
else
need_undirty = _gf_true;
- if (local->op_ret < 0) {
+ if (local->op_ret < 0 && !nothing_failed) {
afr_changelog_post_op_done (frame, this);
goto out;
}