summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/basic/shd_force_inspect.t60
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c20
2 files changed, 78 insertions, 2 deletions
diff --git a/tests/basic/shd_force_inspect.t b/tests/basic/shd_force_inspect.t
new file mode 100644
index 00000000000..ecb4fb0d0f4
--- /dev/null
+++ b/tests/basic/shd_force_inspect.t
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume info;
+
+# Setup a cluster with 3 replicas, and fav child by majority on
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{1..3};
+TEST $CLI volume set $V0 cluster.choose-local off
+TEST $CLI volume set $V0 cluster.self-heal-daemon on
+TEST $CLI volume set $V0 nfs.disable on
+TEST $CLI volume set $V0 cluster.quorum-type none
+TEST $CLI volume set $V0 cluster.favorite-child-by-majority on
+TEST $CLI volume set $V0 cluster.favorite-child-by-mtime on
+TEST $CLI volume set $V0 cluster.metadata-self-heal off
+TEST $CLI volume set $V0 cluster.data-self-heal off
+TEST $CLI volume set $V0 cluster.entry-self-heal off
+TEST $CLI volume start $V0
+sleep 5
+
+# Part I: FUSE Test
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 \
+ --attribute-timeout=0 --entry-timeout=0
+
+cd $M0
+mkdir foo
+dd if=/dev/urandom of=foo/testfile bs=128k count=5 2>/dev/null
+MD5=$(md5sum foo/testfile | cut -d\ -f1)
+
+# Kill the SHD while we setup the test
+pkill -f gluster/glustershd
+
+# Grab the GFID of the file and parent dir
+GFID_PARENT_RAW=$(getfattr -n trusted.gfid -e hex $B0/${V0}1/foo 2>/dev/null | grep trusted.gfid | cut -d= -f2)
+GFID_PARENT_FORMATTED=$(echo "$GFID_PARENT_RAW" | awk '{print substr($1,3,8)"-"substr($1,11,4)"-"substr($1,15,4)"-"substr($1,19,4)"-"substr($1,23,12)}')
+GFID_RAW=$(getfattr -n trusted.gfid -e hex $B0/${V0}1/foo/testfile 2>/dev/null | grep trusted.gfid | cut -d= -f2)
+GFID_FORMATTED=$(echo "$GFID_RAW" | awk '{print substr($1,3,8)"-"substr($1,11,4)"-"substr($1,15,4)"-"substr($1,19,4)"-"substr($1,23,12)}')
+GFID_LINK_B1="$B0/${V0}1/.glusterfs/$(echo $GFID_RAW | awk '{print substr($0,3,2)"/"substr($0,5,2)"/"substr($1,3,8)"-"substr($1,11,4)"-"substr($1,15,4)"-"substr($1,19,4)"-"substr($1,23,12)}')"
+
+# Nuke the file from brick 1
+rm -f $GFID_LINK_B1
+rm -f $B0/${V0}1/foo/testfile
+
+# Now manually queue up the parent directory for healing
+touch $B0/${V0}2/.glusterfs/indices/xattrop/$GFID_PARENT_FORMATTED
+touch $B0/${V0}3/.glusterfs/indices/xattrop/$GFID_PARENT_FORMATTED
+
+# Kick off the SHD and wait 30 seconds for healing to take place
+TEST gluster vol start patchy force
+EXPECT_WITHIN 30 "0" afr_get_pending_heal_count $V0
+
+# Verify the file was healed back to brick 1
+TEST stat $B0/${V0}1/foo/testfile
+
+cleanup
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 59228b1925a..12b031d78e6 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -939,6 +939,7 @@ afr_mark_split_brain_source_sinks (call_frame_t *frame, xlator_t *this,
unsigned char *healed_sinks,
unsigned char *locked_on,
struct afr_reply *replies,
+
afr_transaction_type type)
{
afr_local_t *local = NULL;
@@ -1843,8 +1844,14 @@ afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this,
(int) replies[i].poststat.ia_type,
priv->children[i]->name,
uuid_utoa (replies[i].poststat.ia_gfid));
- ret = -EIO;
- goto out;
+
+ if (priv->gfid_splitbrain_forced_heal &&
+ metadata_selfheal) {
+ *metadata_selfheal = _gf_true;
+ } else {
+ ret = -EIO;
+ goto out;
+ }
}
if (!IA_EQUAL (first, replies[i].poststat, uid)) {
@@ -1887,6 +1894,15 @@ afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this,
*metadata_selfheal = _gf_true;
}
+ /* Force entry healing of directories for SHDs regardless
+ * of the entry healing portion of the change log.
+ */
+ if (IA_ISDIR(first.ia_type) && priv->shd.iamshd &&
+ IA_EQUAL (first, replies[i].poststat, type) &&
+ entry_selfheal) {
+ *entry_selfheal = _gf_true;
+ }
+
if (IA_ISREG(first.ia_type) &&
!IA_EQUAL (first, replies[i].poststat, size)) {
gf_msg_debug (this->name, 0,