diff options
author | Ravishankar N <ravishankar@redhat.com> | 2020-02-11 14:34:48 +0530 |
---|---|---|
committer | Ravishankar N <ravishankar@redhat.com> | 2020-02-18 09:11:40 +0000 |
commit | 06453d77d056fbaa393a137ca277a20e38d2f67e (patch) | |
tree | 596d5803946caaebc018758508593ba2232a2ce1 /tests/bugs/replicate | |
parent | a7fa54ddea3fe429f143b37e4de06a93b49d776a (diff) |
afr: prevent spurious entry heals leading to gfid split-brain
Problem:
In a hyperconverged setup with granular-entry-heal enabled, if a file is
recreated while one of the bricks is down, and an index heal is triggered
(with the brick still down), entry-self heal was doing a spurious heal
with just the 2 good bricks. It was doing a post-op leading to removal
of the filename from .glusterfs/indices/entry-changes as well as
erroneous setting of afr xattrs on the parent. When the brick came up,
the xattrs were cleared, resulting in the renamed file not getting
healed and leading to gfid split-brain and EIO on the mount.
Fix:
Proceed with entry heal only when shd can connect to all bricks of the replica,
just like in data and metadata heal.
fixes: bz#1801624
Change-Id: I916ae26ad1fabf259bc6362da52d433b7223b17e
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Diffstat (limited to 'tests/bugs/replicate')
-rw-r--r-- | tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t | 18 | ||||
-rw-r--r-- | tests/bugs/replicate/bug-1801624-entry-heal.t | 58 |
2 files changed, 62 insertions, 14 deletions
diff --git a/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t index 0767f47fdda..10ce0131f4f 100644 --- a/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t +++ b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t @@ -49,25 +49,15 @@ TEST $CLI volume start $V0 force EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2 -#Kill brick 0 and turn on the client side heal and do ls to trigger the heal. -#The pending xattrs on bricks 1 & 2 should have pending entry on brick 0. -TEST kill_brick $V0 $H0 $B0/${V0}0 +# We were killing one brick and checking that entry heal does not reset the +# pending xattrs for the down brick. Now that we need all bricks to be up for +# entry heal, I'm removing that test from the .t + TEST $CLI volume set $V0 cluster.data-self-heal on TEST $CLI volume set $V0 cluster.metadata-self-heal on TEST $CLI volume set $V0 cluster.entry-self-heal on TEST ls $M0 -EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 -EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 -EXPECT_WITHIN $HEAL_TIMEOUT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 -EXPECT_WITHIN $HEAL_TIMEOUT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 - -#Bring back all the bricks and trigger the heal again by doing ls. Now the -#pending xattrs on all the bricks should be 0. -TEST $CLI volume start $V0 force -EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 -TEST ls $M0 - TEST cat $M0/f1 TEST cat $M0/f2 TEST cat $M0/f3 diff --git a/tests/bugs/replicate/bug-1801624-entry-heal.t b/tests/bugs/replicate/bug-1801624-entry-heal.t new file mode 100644 index 00000000000..94b465181fa --- /dev/null +++ b/tests/bugs/replicate/bug-1801624-entry-heal.t @@ -0,0 +1,58 @@ +#!/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/brick{0,1,2} +TEST $CLI volume set $V0 heal-timeout 5 +TEST $CLI volume start $V0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +TEST $CLI volume heal $V0 granular-entry-heal enable + +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 +echo "Data">$M0/FILE +ret=$? +TEST [ $ret -eq 0 ] + +# Re-create the file when a brick is down. +TEST kill_brick $V0 $H0 $B0/brick1 +TEST rm $M0/FILE +echo "New Data">$M0/FILE +ret=$? +TEST [ $ret -eq 0 ] +EXPECT_WITHIN $HEAL_TIMEOUT "4" get_pending_heal_count $V0 + +# Launching index heal must not reset parent dir afr xattrs or remove granular entry indices. +$CLI volume heal $V0 # CLI will fail but heal is launched anyway. +TEST sleep 5 # give index heal a chance to do one run. +brick0_pending=$(get_hex_xattr trusted.afr.$V0-client-1 $B0/brick0/) +brick2_pending=$(get_hex_xattr trusted.afr.$V0-client-1 $B0/brick2/) +TEST [ $brick0_pending -eq "000000000000000000000002" ] +TEST [ $brick2_pending -eq "000000000000000000000002" ] +EXPECT "FILE" ls $B0/brick0/.glusterfs/indices/entry-changes/00000000-0000-0000-0000-000000000001/ +EXPECT "FILE" ls $B0/brick2/.glusterfs/indices/entry-changes/00000000-0000-0000-0000-000000000001/ + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/brick1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +$CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "0" get_pending_heal_count $V0 + +# No gfid-split-brain (i.e. EIO) must be seen. Try on fresh mount to avoid cached values. +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 +TEST cat $M0/FILE + +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +cleanup; |