diff options
| -rw-r--r-- | tests/basic/shd_force_inspect.t | 60 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 20 |
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, |
