From 9b4de61a136b8e5ba7bf0e48690cdb1292d0dee8 Mon Sep 17 00:00:00 2001 From: Mohit Agrawal Date: Fri, 12 May 2017 21:12:47 +0530 Subject: cluster/dht : User xattrs are not healed after brick stop/start Problem: In a distributed volume custom extended attribute value for a directory does not display correct value after stop/start or added newly brick. If any extended(acl) attribute value is set for a directory after stop/added the brick the attribute(user|acl|quota) value is not updated on brick after start the brick. Solution: First store hashed subvol or subvol(has internal xattr) on inode ctx and consider it as a MDS subvol.At the time of update custom xattr (user,quota,acl, selinux) on directory first check the mds from inode ctx, if mds is not present on inode ctx then throw EINVAL error to application otherwise set xattr on MDS subvol with internal xattr value of -1 and then try to update the attribute on other non MDS volumes also.If mds subvol is down in that case throw an error "Transport endpoint is not connected". In dht_dir_lookup_cbk| dht_revalidate_cbk|dht_discover_complete call dht_call_dir_xattr_heal to heal custom extended attribute. In case of gnfs server if hashed subvol has not found based on loc then wind a call on all subvol to update xattr. Fix: 1) Save MDS subvol on inode ctx 2) Check if mds subvol is present on inode ctx 3) If mds subvol is down then call unwind with error ENOTCONN and if it is up then set new xattr "GF_DHT_XATTR_MDS" to -1 and wind a call on other subvol. 4) If setxattr fop is successful on non-mds subvol then increment the value of internal xattr to +1 5) At the time of directory_lookup check the value of new xattr GF_DHT_XATTR_MDS 6) If value is not 0 in dht_lookup_dir_cbk(other cbk) functions then call heal function to heal user xattr 7) syncop_setxattr on hashed_subvol to reset the value of xattr to 0 if heal is successful on all subvol. Test : To reproduce the issue followed below steps 1) Create a distributed volume and create mount point 2) Create some directory from mount point mkdir tmp{1..5} 3) Kill any one brick from the volume 4) Set extended attribute from mount point on directory setfattr -n user.foo -v "abc" ./tmp{1..5} It will throw error " Transport End point is not connected " for those hashed subvol is down 5) Start volume with force option to start brick process 6) Execute getfattr command on mount point for directory 7) Check extended attribute on brick getfattr -n user.foo /tmp{1..5} It shows correct value for directories for those xattr fop were executed successfully. Note: The patch will resolve xattr healing problem only for fuse mount not for nfs mount. BUG: 1371806 Signed-off-by: Mohit Agrawal Change-Id: I4eb137eace24a8cb796712b742f1d177a65343d5 --- tests/bugs/bug-1368312.t | 30 ++++++------- tests/bugs/bug-1371806.t | 80 +++++++++++++++++++++++++++++++++ tests/bugs/bug-1371806_1.t | 49 +++++++++++++++++++++ tests/bugs/bug-1371806_2.t | 52 ++++++++++++++++++++++ tests/bugs/bug-1371806_3.t | 63 ++++++++++++++++++++++++++ tests/bugs/bug-1371806_acl.t | 90 ++++++++++++++++++++++++++++++++++++++ tests/bugs/distribute/bug-862967.t | 7 ++- 7 files changed, 352 insertions(+), 19 deletions(-) create mode 100644 tests/bugs/bug-1371806.t create mode 100644 tests/bugs/bug-1371806_1.t create mode 100644 tests/bugs/bug-1371806_2.t create mode 100644 tests/bugs/bug-1371806_3.t create mode 100644 tests/bugs/bug-1371806_acl.t (limited to 'tests/bugs') diff --git a/tests/bugs/bug-1368312.t b/tests/bugs/bug-1368312.t index 135048f448e..61e56060e81 100644 --- a/tests/bugs/bug-1368312.t +++ b/tests/bugs/bug-1368312.t @@ -29,46 +29,46 @@ TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; TEST mkdir $M0/tmp1 #Create metadata split-brain -TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST kill_brick $V0 $H0 $B0/${V0}2 TEST chmod 666 $M0/tmp1 TEST $CLI volume start $V0 force -TEST kill_brick $V0 $H0 $B0/${V0}1 -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST kill_brick $V0 $H0 $B0/${V0}3 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 TEST chmod 757 $M0/tmp1 TEST $CLI volume start $V0 force -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 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 3 EXPECT 2 get_pending_heal_count $V0 -TEST kill_brick $V0 $H0 $B0/${V0}2 +TEST kill_brick $V0 $H0 $B0/${V0}4 TEST chmod 755 $M0/tmp1 TEST $CLI volume start $V0 force -TEST kill_brick $V0 $H0 $B0/${V0}3 -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 +TEST kill_brick $V0 $H0 $B0/${V0}5 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4 TEST chmod 766 $M0/tmp1 TEST $CLI volume start $V0 force -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 3 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 5 EXPECT 4 get_pending_heal_count $V0 -TEST kill_brick $V0 $H0 $B0/${V0}4 +TEST kill_brick $V0 $H0 $B0/${V0}0 TEST chmod 765 $M0/tmp1 TEST $CLI volume start $V0 force -TEST kill_brick $V0 $H0 $B0/${V0}5 -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4 +TEST kill_brick $V0 $H0 $B0/${V0}1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 TEST chmod 756 $M0/tmp1 TEST $CLI volume start $V0 force -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4 -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 5 +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 6 get_pending_heal_count $V0 diff --git a/tests/bugs/bug-1371806.t b/tests/bugs/bug-1371806.t new file mode 100644 index 00000000000..7dc1613a4f2 --- /dev/null +++ b/tests/bugs/bug-1371806.t @@ -0,0 +1,80 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../dht.rc +cleanup; + +function get_getfattr { + local path=$1 + echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//' +} + +function set_fattr { + for i in `seq 1 10` + do + setfattr -n user.foo -v "newabc" ./tmp${i} + if [ "$?" = "0" ] + then + succ=$((succ+1)) + else + fail=$((fail+1)) + fi + done +} + + + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3,4,5} +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +TEST mkdir tmp{1..10} + +##First set user.foo xattr with value abc on all dirs + +TEST setfattr -n user.foo -v "abc" ./tmp{1..10} +EXPECT "abc" get_getfattr ./tmp{1..10} +EXPECT "abc" get_getfattr $B0/${V0}5/tmp{1..10} + +TEST kill_brick $V0 $H0 $B0/${V0}5 +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "5" online_brick_count + +succ=fail=0 +## set user.foo xattr with value newabc after kill one brick +set_fattr +TEST $CLI volume start $V0 force +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "6" online_brick_count + +cd - +TEST umount $M0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +## At this point dht code will heal xattr on down brick only for those dirs +## hashed subvol was up at the time of update xattr +TEST stat ./tmp{1..10} + +## Count the user.foo xattr value with abc on mount point and compare with fail value +count=`getfattr -n user.foo ./tmp{1..10} | grep "user.foo" | grep -iw "abc" | wc -l` +EXPECT "$fail" echo $count + +## Count the user.foo xattr value with newabc on mount point and compare with succ value +count=`getfattr -n user.foo ./tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l` +EXPECT "$succ" echo $count + +## Count the user.foo xattr value with abc on brick and compare with succ value +count=`getfattr -n user.foo $B0/${V0}5/tmp{1..10} | grep "user.foo" | grep -iw "abc" | wc -l` +EXPECT "$fail" echo $count + +## Count the user.foo xattr value with newabc on brick and compare with succ value +count=`getfattr -n user.foo $B0/${V0}5/tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l` +EXPECT "$succ" echo $count + + +cd - +cleanup +exit diff --git a/tests/bugs/bug-1371806_1.t b/tests/bugs/bug-1371806_1.t new file mode 100644 index 00000000000..44a57a9e5d2 --- /dev/null +++ b/tests/bugs/bug-1371806_1.t @@ -0,0 +1,49 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../dht.rc +cleanup; + +function get_getfattr { + local path=$1 + echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//' +} + +function remove_mds_xattr { + + for i in `seq 1 10` + do + setfattr -x trusted.glusterfs.dht.mds $1/tmp${i} 2> /dev/null + done +} + + + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3} +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; + +cd $M0 +TEST mkdir tmp{1..10} + +##Remove internal mds xattr from all directory +remove_mds_xattr $B0/${V0}0 +remove_mds_xattr $B0/${V0}1 +remove_mds_xattr $B0/${V0}2 +remove_mds_xattr $B0/${V0}3 + +cd - +umount $M0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; +cd $M0 + +TEST setfattr -n user.foo -v "abc" ./tmp{1..10} +EXPECT "abc" get_getfattr ./tmp{1..10} + +cd - +cleanup +exit diff --git a/tests/bugs/bug-1371806_2.t b/tests/bugs/bug-1371806_2.t new file mode 100644 index 00000000000..e6aa8e7c1ad --- /dev/null +++ b/tests/bugs/bug-1371806_2.t @@ -0,0 +1,52 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../dht.rc +cleanup; + +function get_getfattr { + local path=$1 + echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//' +} + +function remove_mds_xattr { + + for i in `seq 1 10` + do + setfattr -x trusted.glusterfs.dht.mds $1/tmp${i} 2> /dev/null + done +} + + + + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3} +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0; +cd $M0 +TEST mkdir tmp{1..10} + +##Remove internal mds xattr from all directory +remove_mds_xattr $B0/${V0}0 +remove_mds_xattr $B0/${V0}1 +remove_mds_xattr $B0/${V0}2 +remove_mds_xattr $B0/${V0}3 + +##First set user.foo xattr with value abc on all dirs + +TEST setfattr -n user.foo -v "abc" ./tmp{1..10} +EXPECT "abc" get_getfattr ./tmp{1..10} +EXPECT "abc" get_getfattr $B0/${V0}0/tmp{1..10} +EXPECT "abc" get_getfattr $B0/${V0}1/tmp{1..10} +EXPECT "abc" get_getfattr $B0/${V0}2/tmp{1..10} +EXPECT "abc" get_getfattr $B0/${V0}3/tmp{1..10} + +cd - +TEST umount $M0 + +cd - +cleanup +exit diff --git a/tests/bugs/bug-1371806_3.t b/tests/bugs/bug-1371806_3.t new file mode 100644 index 00000000000..cb13f37c737 --- /dev/null +++ b/tests/bugs/bug-1371806_3.t @@ -0,0 +1,63 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../dht.rc +cleanup; + +function get_getfattr { + local path=$1 + echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//' +} + +function set_fattr { + for i in `seq 1 10` + do + setfattr -n user.foo -v "newabc" ./tmp${i} + if [ "$?" = "0" ] + then + succ=$((succ+1)) + else + fail=$((fail+1)) + fi + done +} + + + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3} +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0; + +cd $M0 +TEST mkdir tmp{1..10} + +TEST kill_brick $V0 $H0 $B0/${V0}3 +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "3" online_brick_count + +succ=fail=0 +## set user.foo xattr with value newabc after kill one brick +set_fattr +TEST $CLI volume start $V0 force +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "4" online_brick_count + +cd - +TEST umount $M0 +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0; + +cd $M0 +## At this point dht code will heal xattr on down brick only for those dirs +## hashed subvol was up at the time of update xattr +TEST stat ./tmp{1..10} + + +## Count the user.foo xattr value with newabc on brick and compare with succ value +count=`getfattr -n user.foo $B0/${V0}3/tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l` +EXPECT "$succ" echo $count + + +cd - +cleanup +exit diff --git a/tests/bugs/bug-1371806_acl.t b/tests/bugs/bug-1371806_acl.t new file mode 100644 index 00000000000..aa41e04b96f --- /dev/null +++ b/tests/bugs/bug-1371806_acl.t @@ -0,0 +1,90 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; +TEST useradd tmpuser + +function set_facl_user { + for i in `seq 1 10` + do + setfacl -m u:tmpuser:rw ./tmp${i} + if [ "$?" = "0" ] + then + succ=$((succ+1)) + else + fail=$((fail+1)) + fi + done +} + +function set_facl_default { + for i in `seq 1 10` + do + setfacl -m d:o:rw ./tmp${i} + if [ "$?" = "0" ] + then + succ1=$((succ1+1)) + else + fail1=$((fail1+1)) + fi + done +} + + + + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3,4,5} +TEST $CLI volume set $V0 diagnostics.client-log-level DEBUG +TEST $CLI volume start $V0 + +TEST glusterfs --volfile-id=$V0 --acl --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +TEST mkdir tmp{1..10} +TEST setfacl -m u:tmpuser:rwx ./tmp{1..10} +count=`getfacl -p $M0/tmp{1..10} | grep -c "user:tmpuser:rwx"` +EXPECT "10" echo $count +TEST setfacl -m d:o:rwx ./tmp{1..10} +count=`getfacl -p $M0/tmp{1..10} | grep -c "default:other::rwx"` +EXPECT "10" echo $count +count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "user:tmpuser:rwx"` +EXPECT "10" echo $count +count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "default:other::rwx"` +EXPECT "10" echo $count + + +TEST kill_brick $V0 $H0 $B0/${V0}5 +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "5" online_brick_count + +succ=fail=0 +## Update acl attributes on dir after kill one brick +set_facl_user +succ1=fail1=0 +set_facl_default + +TEST $CLI volume start $V0 force +EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "6" online_brick_count + +cd - +TEST umount $M0 +TEST glusterfs --volfile-id=$V0 --acl --volfile-server=$H0 --entry-timeout=0 $M0; + +cd $M0 +## At this point dht will heal xatts on down brick only for those hashed_subvol +## was up at the time of updated xattrs +TEST stat ./tmp{1..10} + +## Compare succ value with updated acl attributes +count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "user:tmpuser:rw-"` +EXPECT "$succ" echo $count + + +count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "default:other::rw-"` +EXPECT "$succ1" echo $count + +cd - +userdel --force tmpuser +cleanup diff --git a/tests/bugs/distribute/bug-862967.t b/tests/bugs/distribute/bug-862967.t index 09dac376d94..2fb0848bd7c 100644 --- a/tests/bugs/distribute/bug-862967.t +++ b/tests/bugs/distribute/bug-862967.t @@ -37,7 +37,7 @@ chown 1:1 $M0/dir; # Kill a brick process -kill_brick $V0 $H0 $B0/${V0}1 +kill_brick $V0 $H0 $B0/${V0}2 # change dir ownership NEW_UID=36; NEW_GID=36; @@ -51,9 +51,8 @@ sleep 10; ls -l $M0/dir; # check if uid/gid is healed on backend brick which was taken down -BACKEND_UID=`stat -c %u $B0/${V0}1/dir`; -BACKEND_GID=`stat -c %g $B0/${V0}1/dir`; - +BACKEND_UID=`stat -c %u $B0/${V0}2/dir`; +BACKEND_GID=`stat -c %g $B0/${V0}2/dir`; EXPECT "0" uid_gid_compare $NEW_UID $NEW_GID $BACKEND_UID $BACKEND_GID -- cgit