diff options
-rw-r--r-- | tests/bitrot/bug-1294786.t | 68 | ||||
-rw-r--r-- | tests/cluster.rc | 7 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 22 |
3 files changed, 97 insertions, 0 deletions
diff --git a/tests/bitrot/bug-1294786.t b/tests/bitrot/bug-1294786.t new file mode 100644 index 00000000000..2bfae36fd86 --- /dev/null +++ b/tests/bitrot/bug-1294786.t @@ -0,0 +1,68 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../cluster.rc + +function get_bitd_count_1 { + ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | grep $H1 | wc -l +} + +function get_bitd_count_2 { + ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | grep $H2 | wc -l +} + +function get_node_uuid { + getfattr -n trusted.glusterfs.node-uuid --only-values $M0/FILE 2>/dev/null +} + +cleanup; + +TEST launch_cluster 2 + +TEST $CLI_1 peer probe $H2; +EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count; + +TEST $CLI_1 volume create $V0 replica 2 $H1:$B1 $H2:$B2 +EXPECT 'Created' volinfo_field_1 $V0 'Status'; + +TEST $CLI_1 volume start $V0 +EXPECT 'Started' volinfo_field_1 $V0 'Status'; + +uuid1=$($CLI_1 system:: uuid get | awk '{print $2}') +uuid2=$($CLI_2 system:: uuid get | awk '{print $2}') + +##Mount $V0 +TEST $GFS --volfile-id=$V0 --volfile-server=$H1 $M0 + +#Enable bitrot +TEST $CLI_1 volume bitrot $V0 enable +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_2 + +#Create sample file +TEST `echo "1234" > $M0/FILE` + +EXPECT "$uuid1" get_node_uuid; + +#Corrupt file from back-end +TEST stat $B1/FILE +echo "Corrupted data" >> $B1/FILE +#Manually set bad-file xattr since we can't wait for an hour for scrubber. +TEST setfattr -n trusted.bit-rot.bad-file -v 0x3100 $B1/FILE + +TEST $CLI_1 volume stop $V0 +TEST $CLI_1 volume start $V0 +EXPECT 'Started' volinfo_field_1 $V0 'Status'; +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status_1 $V0 $H1 $B1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status_1 $V0 $H2 $B2 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count_2 +#Trigger lookup so that bitrot xlator marks file as bad in its inode context. +TEST stat $M0/FILE + +EXPECT "$uuid2" get_node_uuid; + +cleanup; diff --git a/tests/cluster.rc b/tests/cluster.rc index d210ca2932e..467bbcb06e1 100644 --- a/tests/cluster.rc +++ b/tests/cluster.rc @@ -170,3 +170,10 @@ function volinfo_field_2() $CLI_2 volume info $vol | grep "^$field: " | sed 's/.*: //'; } + +function brick_up_status_1 { + local vol=$1 + local host=$2 + local brick=$3 + $CLI_1 volume status $vol $host:$brick --xml | sed -ne 's/.*<status>\([01]\)<\/status>/\1/p' +} diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index 42db6d083f2..94e694686f6 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -1605,6 +1605,17 @@ br_stub_getxattr (call_frame_t *frame, xlator_t *this, goto wind; } + /** + * If xattr is node-uuid and the inode is marked bad, return EIO. + * Returning EIO would result in AFR to choose correct node-uuid + * coresponding to the subvolume * where the good copy of the + * file resides. + */ + if (IA_ISREG (loc->inode->ia_type) && XATTR_IS_NODE_UUID (name) && + br_stub_check_bad_object (this, loc->inode, &op_ret, &op_errno)) { + goto unwind; + } + if (br_stub_is_internal_xattr (name)) goto unwind; @@ -1668,6 +1679,17 @@ br_stub_fgetxattr (call_frame_t *frame, xlator_t *this, goto wind; } + /** + * If xattr is node-uuid and the inode is marked bad, return EIO. + * Returning EIO would result in AFR to choose correct node-uuid + * coresponding to the subvolume * where the good copy of the + * file resides. + */ + if (IA_ISREG (fd->inode->ia_type) && XATTR_IS_NODE_UUID (name) && + br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno)) { + goto unwind; + } + if (br_stub_is_internal_xattr (name)) goto unwind; |