ALWAYS_EXCEPT="$SANITY_EXCEPT 42a 42b 42c 77k"
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
-# skipped tests: LU-8411 LU-9096 LU-9054 LU-10680 ..
-ALWAYS_EXCEPT=" 407 253 312 160f 160g $ALWAYS_EXCEPT"
+# skipped tests: LU-8411 LU-9096 LU-9054 ..
+ALWAYS_EXCEPT=" 407 253 312 $ALWAYS_EXCEPT"
+# skipped tests: LU-4684
+ALWAYS_EXCEPT=" 17n 160d 230 316 $ALWAYS_EXCEPT"
# Check Grants after these tests
GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c"
. ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
init_logging
+if [[ $MDSCOUNT -gt 1 ]]; then
+ # bug number: LU-11161
+ ALWAYS_EXCEPT+=" 160g"
+fi
+
# 5 12 (min)"
[ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
}
run_test 27G "Clear OST pool from stripe"
+test_27H() {
+ [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.11.53) ]] &&
+ skip "Need MDS version newer than 2.11.53"
+ [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
+ test_mkdir $DIR/$tdir
+ $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
+ touch $DIR/$tdir/$tfile
+ $LFS getstripe -c $DIR/$tdir/$tfile
+ [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
+ error "two-stripe file doesn't have two stripes"
+
+ dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
+ $LFS getstripe -y $DIR/$tdir/$tfile
+ (( $($LFS getstripe -y $DIR/$tdir/$tfile |
+ egrep -c "l_ost_idx: [02]$") == "2" )) ||
+ error "expected l_ost_idx: [02]$ not matched"
+}
+run_test 27H "Set specific OSTs stripe"
+
# createtest also checks that device nodes are created and
# then visible correctly (#2091)
test_28() { # bug 2091
}
run_test 77g "checksum error on OST write, read"
-test_77j() { # bug 13805
- [ $PARALLEL == "yes" ] && skip "skip parallel run"
- $GSS && skip_env "could not run with gss"
-
- #define OBD_FAIL_OSC_CKSUM_ADLER_ONLY 0x40c
- lctl set_param fail_loc=0x40c
- remount_client $MOUNT
- lctl set_param fail_loc=0
- # wait async osc connect to finish and reflect updated state value
- local i
- for (( i=0; i < OSTCOUNT; i++ )) ; do
- wait_osc_import_state client ost$((i+1)) FULL
- done
-
- for VALUE in $(lctl get_param osc.*osc-[^mM]*.checksum_type); do
- PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
- algo=$(lctl get_param -n $PARAM | sed 's/.*\[\(.*\)\].*/\1/g')
- [ "$algo" = "adler" ] || error "algo set to $algo instead of adler"
- done
- remount_client $MOUNT
-}
-run_test 77j "client only supporting ADLER32"
-
test_77k() { # LU-10906
[ $PARALLEL == "yes" ] && skip "skip parallel run"
$GSS && skip_env "could not run with gss"
run_test 102h "grow xattr from inside inode to external block"
test_102ha() {
- large_xattr_enabled || skip_env "large_xattr disabled"
+ large_xattr_enabled || skip_env "ea_inode feature disabled"
grow_xattr $(max_xattr_size)
}
}
run_test 102r "set EAs with empty values"
+test_102s() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.52) ] &&
+ skip "MDS needs to be at least 2.11.52"
+
+ local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
+
+ save_lustre_params client "llite.*.xattr_cache" > $save
+
+ for cache in 0 1; do
+ lctl set_param llite.*.xattr_cache=$cache
+
+ rm -f $DIR/$tfile
+ touch $DIR/$tfile || error "touch"
+ for prefix in lustre security system trusted user; do
+ # Note getxattr() may fail with 'Operation not
+ # supported' or 'No such attribute' depending
+ # on prefix and cache.
+ getfattr -n $prefix.n102s $DIR/$tfile &&
+ error "getxattr '$prefix.n102s' should fail (cache = $cache)"
+ done
+ done
+
+ restore_lustre_params < $save
+}
+run_test 102s "getting nonexistent xattrs should fail"
+
+test_102t() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.52) ] &&
+ skip "MDS needs to be at least 2.11.52"
+
+ local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
+
+ save_lustre_params client "llite.*.xattr_cache" > $save
+
+ for cache in 0 1; do
+ lctl set_param llite.*.xattr_cache=$cache
+
+ for buf_size in 0 256; do
+ rm -f $DIR/$tfile
+ touch $DIR/$tfile || error "touch"
+ setfattr -n user.multiop $DIR/$tfile
+ $MULTIOP $DIR/$tfile oa$buf_size ||
+ error "cannot get zero length xattr value (buf_size = $buf_size)"
+ done
+ done
+
+ restore_lustre_params < $save
+}
+run_test 102t "zero length xattr values handled correctly"
+
run_acl_subtest()
{
$LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
check_stats $SINGLEMDS "getattr" 1
fi
+ # Sleep to avoid a cached response.
+ #define OBD_STATFS_CACHE_SECONDS 1
+ sleep 2
$LFS df || error "lfs failed"
check_stats $SINGLEMDS "statfs" 1
proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
+# Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
+# not honor the -ignore_readdir_race option correctly. So we call
+# error_ignore() rather than error() in these cases. See LU-11152.
+error_133() {
+ if (find --version; do_facet mds1 find --version) |
+ grep -q '\b4\.5\.1[1-4]\b'; then
+ error_ignore LU-11152 "$@"
+ else
+ error "$@"
+ fi
+}
+
test_133f() {
# First without trusting modes.
local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
-not -name force_lbug \
-not -name changelog_mask \
-exec badarea_io '{}' \; ||
- error "find $proc_dirs failed"
+ error_133 "find $proc_dirs failed"
}
run_test 133f "Check reads/writes of client lustre proc files with bad area io"
-not -name force_lbug \
-not -name changelog_mask \
-exec badarea_io '{}' \\\; ||
- error "$facet find $facet_proc_dirs failed"
+ error_133 "$facet find $facet_proc_dirs failed"
done
# remount the FS in case writes/reads /proc break the FS
run_test 160e "changelog negative testing (should return errors)"
test_160f() {
- remote_mds_nodsh && skip "remote MDS with nodsh"
+ remote_mds_nodsh && skip "remote MDS with nodsh" && return
[[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.10.56) ]] ||
- skip "Need MDS version at least 2.10.56"
+ { skip "Need MDS version at least 2.10.56"; return 0; }
local mdts=$(comma_list $(mdts_nodes))
# Create a user
changelog_register || error "first changelog_register failed"
changelog_register || error "second changelog_register failed"
- local cl_users=(${CL_USERS[$SINGLEMDS]})
- local cl_user1="${cl_users[0]}"
- local cl_user2="${cl_users[1]}"
+ local cl_users
+ declare -A cl_user1
+ declare -A cl_user2
+ local user_rec1
+ local user_rec2
+ local i
# generate some changelog records to accumulate on each MDT
test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
error "create $DIR/$tdir/$tfile failed"
# check changelogs have been generated
- nbcl=$(changelog_dump | wc -l)
+ local nbcl=$(changelog_dump | wc -l)
[[ $nbcl -eq 0 ]] && error "no changelogs found"
- # changelog_gc=1 should be set by default
for param in "changelog_max_idle_time=10" \
+ "changelog_gc=1" \
"changelog_min_gc_interval=2" \
"changelog_min_free_cat_entries=3"; do
local MDT0=$(facet_svc $SINGLEMDS)
do_nodes $mdts $LCTL set_param mdd.*.$param
done
+ # force cl_user2 to be idle (1st part)
+ sleep 9
+
# simulate changelog catalog almost full
#define OBD_FAIL_CAT_FREE_RECORDS 0x1313
do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
- sleep 6
- local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user1)
- [ -n "$user_rec1" ] ||
- error "User $cl_user1 not found in changelog_users"
- __changelog_clear $SINGLEMDS $cl_user1 +2
- local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user1)
- [ -n "$user_rec2" ] ||
- error "User $cl_user1 not found in changelog_users"
- echo "verifying user clear: $user_rec1 + 2 == $user_rec2"
- [ $((user_rec1 + 2)) == $user_rec2 ] ||
- error "user index expected $user_rec1 + 2, but is $user_rec2"
- sleep 5
+ for i in $(seq $MDSCOUNT); do
+ cl_users=(${CL_USERS[mds$i]})
+ cl_user1[mds$i]="${cl_users[0]}"
+ cl_user2[mds$i]="${cl_users[1]}"
+
+ [ -n "${cl_user1[mds$i]}" ] ||
+ error "mds$i: no user registered"
+ [ -n "${cl_user2[mds$i]}" ] ||
+ error "mds$i: only ${cl_user2[mds$i]} is registered"
+
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ __changelog_clear mds$i ${cl_user1[mds$i]} +2
+ user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
+ "$user_rec1 + 2 == $user_rec2"
+ [ $((user_rec1 + 2)) == $user_rec2 ] ||
+ error "mds$i: user ${cl_user1[mds$i]} index expected " \
+ "$user_rec1 + 2, but is $user_rec2"
+ user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user2[mds$i]} not registered"
+ [ $user_rec1 == $user_rec2 ] ||
+ error "mds$i: user ${cl_user2[mds$i]} index expected " \
+ "$user_rec1, but is $user_rec2"
+ done
+
+ # force cl_user2 to be idle (2nd part) and to reach
+ # changelog_max_idle_time
+ sleep 2
# generate one more changelog to trigger fail_loc
- rm -rf $DIR/$tdir || error "rm -rf $tdir failed"
+ createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
+ error "create $DIR/$tdir/${tfile}bis failed"
# ensure gc thread is done
- wait_update_facet $SINGLEMDS \
- "ps -e -o comm= | grep chlg_gc_thread" "" 20
-
- # check user still registered
- changelog_users $SINGLEMDS | grep -q "$cl_user1" ||
- error "User $cl_user1 not found in changelog_users"
- # check user2 unregistered
- changelog_users $SINGLEMDS | grep -q "$cl_user2" &&
- error "User $cl_user2 still found in changelog_users"
-
- # check changelogs are present and starting at $user_rec2 + 1
- local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
- awk '{ print $1; exit; }')
+ for i in $(mdts_nodes); do
+ wait_update $i \
+ "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
+ error "$i: GC-thread not done"
+ done
- echo "verifying min purge: $user_rec2 + 1 == $first_rec"
- [ $((user_rec2 + 1)) == $first_rec ] ||
- error "first index should be $user_rec2 + 1, but is $first_rec"
+ local first_rec
+ for i in $(seq $MDSCOUNT); do
+ # check cl_user1 still registered
+ changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ # check cl_user2 unregistered
+ changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
+ error "mds$i: User ${cl_user2[mds$i]} still registered"
+
+ # check changelogs are present and starting at $user_rec1 + 1
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ first_rec=$($LFS changelog $(facet_svc mds$i) |
+ awk '{ print $1; exit; }')
+
+ echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
+ [ $((user_rec1 + 1)) == $first_rec ] ||
+ error "mds$i: first index should be $user_rec1 + 1, " \
+ "but is $first_rec"
+ done
}
run_test 160f "changelog garbage collect (timestamped users)"
# Create a user
changelog_register || error "first changelog_register failed"
changelog_register || error "second changelog_register failed"
- local cl_users=(${CL_USERS[$SINGLEMDS]})
- local cl_user1="${cl_users[0]}"
- local cl_user2="${cl_users[1]}"
+ local cl_users
+ declare -A cl_user1
+ declare -A cl_user2
+ local user_rec1
+ local user_rec2
+ local i
# generate some changelog records to accumulate on each MDT
test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
error "create $DIR/$tdir/$tfile failed"
# check changelogs have been generated
- nbcl=$(changelog_dump | wc -l)
+ local nbcl=$(changelog_dump | wc -l)
[[ $nbcl -eq 0 ]] && error "no changelogs found"
- # changelog_gc=1 should be set by default
for param in "changelog_max_idle_indexes=$((nbcl / 2))" \
+ "changelog_gc=1" \
"changelog_min_gc_interval=2" \
"changelog_min_free_cat_entries=3"; do
local MDT0=$(facet_svc $SINGLEMDS)
#define OBD_FAIL_CAT_FREE_RECORDS 0x1313
do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
- local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user1)
-
- __changelog_clear $SINGLEMDS $cl_user1 +3
-
- local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user1)
+ for i in $(seq $MDSCOUNT); do
+ cl_users=(${CL_USERS[mds$i]})
+ cl_user1[mds$i]="${cl_users[0]}"
+ cl_user2[mds$i]="${cl_users[1]}"
+
+ [ -n "${cl_user1[mds$i]}" ] ||
+ error "mds$i: no user registered"
+ [ -n "${cl_user2[mds$i]}" ] ||
+ error "mds$i: only ${cl_user1[mds$i]} is registered"
+
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ __changelog_clear mds$i ${cl_user1[mds$i]} +2
+ user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
+ "$user_rec1 + 2 == $user_rec2"
+ [ $((user_rec1 + 2)) == $user_rec2 ] ||
+ error "mds$i: user ${cl_user1[mds$i]} index expected " \
+ "$user_rec1 + 2, but is $user_rec2"
+ user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user2[mds$i]} not registered"
+ [ $user_rec1 == $user_rec2 ] ||
+ error "mds$i: user ${cl_user2[mds$i]} index expected " \
+ "$user_rec1, but is $user_rec2"
+ done
- echo "verifying user clear: $user_rec1 + 3 == $user_rec2"
- [ $((user_rec1 + 3)) == $user_rec2 ] ||
- error "user index expected $user_rec1 + 3, but is $user_rec2"
+ # ensure we are past the previous changelog_min_gc_interval set above
+ sleep 2
# generate one more changelog to trigger fail_loc
- rm -rf $DIR/$tdir || error "rm -rf $tdir failed"
+ createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
+ error "create $DIR/$tdir/${tfile}bis failed"
# ensure gc thread is done
- wait_update_facet $SINGLEMDS \
- "ps -e -o comm= | grep chlg_gc_thread" "" 20
-
- # check user still registered
- [ -n "$(changelog_user_rec $SINGLEMDS $cl_user1)" ] ||
- error "User $cl_user1 not found in changelog_users"
- # check user2 unregistered
- [ -z "$(changelog_user_rec $SINGLEMDS $cl_user2)" ] ||
- error "User $cl_user2 still found in changelog_users"
-
- # check changelogs are present and starting at $user_rec2 + 1
- local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
- awk '{ print $1; exit; }')
+ for i in $(mdts_nodes); do
+ wait_update $i \
+ "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
+ error "$i: GC-thread not done"
+ done
- echo "verifying min purge: $user_rec2 + 1 == $first_rec"
- [ $((user_rec2 + 1)) == $first_rec ] ||
- error "first index should be $user_rec2 + 1, but is $first_rec"
+ local first_rec
+ for i in $(seq $MDSCOUNT); do
+ # check cl_user1 still registered
+ changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ # check cl_user2 unregistered
+ changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
+ error "mds$i: User ${cl_user2[mds$i]} still registered"
+
+ # check changelogs are present and starting at $user_rec1 + 1
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ first_rec=$($LFS changelog $(facet_svc mds$i) |
+ awk '{ print $1; exit; }')
+
+ echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
+ [ $((user_rec1 + 1)) == $first_rec ] ||
+ error "mds$i: first index should be $user_rec1 + 1, " \
+ "but is $first_rec"
+ done
}
run_test 160g "changelog garbage collect (old users)"
test_160h() {
+ remote_mds_nodsh && skip "remote MDS with nodsh" && return
+ [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.10.56) ]] ||
+ { skip "Need MDS version at least 2.10.56"; return 0; }
+
+ local mdts=$(comma_list $(mdts_nodes))
+
+ # Create a user
+ changelog_register || error "first changelog_register failed"
+ changelog_register || error "second changelog_register failed"
+ local cl_users
+ declare -A cl_user1
+ declare -A cl_user2
+ local user_rec1
+ local user_rec2
+ local i
+
+ # generate some changelog records to accumulate on each MDT
+ test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
+ createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
+ error "create $DIR/$tdir/$tfile failed"
+
+ # check changelogs have been generated
+ local nbcl=$(changelog_dump | wc -l)
+ [[ $nbcl -eq 0 ]] && error "no changelogs found"
+
+ for param in "changelog_max_idle_time=10" \
+ "changelog_gc=1" \
+ "changelog_min_gc_interval=2"; do
+ local MDT0=$(facet_svc $SINGLEMDS)
+ local var="${param%=*}"
+ local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
+
+ stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
+ do_nodes $mdts $LCTL set_param mdd.*.$param
+ done
+
+ # force cl_user2 to be idle (1st part)
+ sleep 9
+
+ for i in $(seq $MDSCOUNT); do
+ cl_users=(${CL_USERS[mds$i]})
+ cl_user1[mds$i]="${cl_users[0]}"
+ cl_user2[mds$i]="${cl_users[1]}"
+
+ [ -n "${cl_user1[mds$i]}" ] ||
+ error "mds$i: no user registered"
+ [ -n "${cl_user2[mds$i]}" ] ||
+ error "mds$i: only ${cl_user2[mds$i]} is registered"
+
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ __changelog_clear mds$i ${cl_user1[mds$i]} +2
+ user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
+ "$user_rec1 + 2 == $user_rec2"
+ [ $((user_rec1 + 2)) == $user_rec2 ] ||
+ error "mds$i: user ${cl_user1[mds$i]} index expected " \
+ "$user_rec1 + 2, but is $user_rec2"
+ user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
+ [ -n "$user_rec2" ] ||
+ error "mds$i: User ${cl_user2[mds$i]} not registered"
+ [ $user_rec1 == $user_rec2 ] ||
+ error "mds$i: user ${cl_user2[mds$i]} index expected " \
+ "$user_rec1, but is $user_rec2"
+ done
+
+ # force cl_user2 to be idle (2nd part) and to reach
+ # changelog_max_idle_time
+ sleep 2
+
+ # force each GC-thread start and block then
+ # one per MDT/MDD, set fail_val accordingly
+ #define OBD_FAIL_FORCE_GC_THREAD 0x1316
+ do_nodes $mdts $LCTL set_param fail_loc=0x1316
+
+ # generate more changelogs to trigger fail_loc
+ createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
+ error "create $DIR/$tdir/${tfile}bis failed"
+
+ # stop MDT to stop GC-thread, should be done in back-ground as it will
+ # block waiting for the thread to be released and exit
+ declare -A stop_pids
+ for i in $(seq $MDSCOUNT); do
+ stop mds$i &
+ stop_pids[mds$i]=$!
+ done
+
+ for i in $(mdts_nodes); do
+ local facet
+ local nb=0
+ local facets=$(facets_up_on_host $i)
+
+ for facet in ${facets//,/ }; do
+ if [[ $facet == mds* ]]; then
+ nb=$((nb + 1))
+ fi
+ done
+ # ensure each MDS's gc threads are still present and all in "R"
+ # state (OBD_FAIL_FORCE_GC_THREAD effect!)
+ [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
+ error "$i: expected $nb GC-thread"
+ wait_update $i \
+ "ps -C chlg_gc_thread -o state --no-headers | uniq" \
+ "R" 20 ||
+ error "$i: GC-thread not found in R-state"
+ # check umounts of each MDT on MDS have reached kthread_stop()
+ [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
+ error "$i: expected $nb umount"
+ wait_update $i \
+ "ps -C umount -o state --no-headers | uniq" "D" 20 ||
+ error "$i: umount not found in D-state"
+ done
+
+ # release all GC-threads
+ do_nodes $mdts $LCTL set_param fail_loc=0
+
+ # wait for MDT stop to complete
+ for i in $(seq $MDSCOUNT); do
+ wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
+ done
+
+ # XXX
+ # may try to check if any orphan changelog records are present
+ # via ldiskfs/zfs and llog_reader...
+
+ # re-start/mount MDTs
+ for i in $(seq $MDSCOUNT); do
+ start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
+ error "Fail to start mds$i"
+ done
+
+ local first_rec
+ for i in $(seq $MDSCOUNT); do
+ # check cl_user1 still registered
+ changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ # check cl_user2 unregistered
+ changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
+ error "mds$i: User ${cl_user2[mds$i]} still registered"
+
+ # check changelogs are present and starting at $user_rec1 + 1
+ user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
+ [ -n "$user_rec1" ] ||
+ error "mds$i: User ${cl_user1[mds$i]} not registered"
+ first_rec=$($LFS changelog $(facet_svc mds$i) |
+ awk '{ print $1; exit; }')
+
+ echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
+ [ $((user_rec1 + 1)) == $first_rec ] ||
+ error "mds$i: first index should be $user_rec1 + 1, " \
+ "but is $first_rec"
+ done
+}
+run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
+ "during mount"
+
+test_160i() {
local mdts=$(comma_list $(mdts_nodes))
error "changelogs are off on mds$i"
done
}
-run_test 160h "changelog user register/unregister race"
+run_test 160i "changelog user register/unregister race"
test_161a() {
[ $PARALLEL == "yes" ] && skip "skip parallel run"
dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
error "dd to $DIR/$tfile failed"
+ #force write to complete before dropping OST cache & checking memory
+ sync
+
local total=$(facet_meminfo ost1 MemTotal)
echo "Total memory: $total KiB"
}
run_test 258b "verify i_mutex security behavior"
+test_259() {
+ local file=$DIR/$tfile
+ local before
+ local after
+
+ [ "$(facet_fstype mds1)" != "ldiskfs" ] &&
+ skip "ldiskfs only test" && return
+
+ stack_trap "rm -f $file" EXIT
+
+ wait_delete_completed
+ before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
+ echo "before: $before"
+
+ $LFS setstripe -i 0 -c 1 $file
+ dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
+ sync_all_data
+ after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
+ echo "after write: $after"
+
+#define OBD_FAIL_OSD_FAIL_AT_TRUNCATE 0x2301
+ do_facet ost1 $LCTL set_param fail_loc=0x2301
+ $TRUNCATE $file 0
+ after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
+ echo "after truncate: $after"
+
+ stop ost1
+ do_facet ost1 $LCTL set_param fail_loc=0
+ start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
+ sleep 2
+ after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
+ echo "after restart: $after"
+ [ $((after - before)) -ge $(fs_log_size ost1) ] &&
+ error "missing truncate?"
+
+ return 0
+}
+run_test 259 "crash at delayed truncate"
+
test_260() {
#define OBD_FAIL_MDC_CLOSE 0x806
$LCTL set_param fail_loc=0x80000806
}
run_test 271c "DoM: IO lock at open saves enqueue RPCs"
+cleanup_271def_tests() {
+ trap 0
+ rm -f $1
+}
+
+test_271d() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.57) ] &&
+ skip "Need MDS version at least 2.10.57" && return
+
+ local dom=$DIR/$tdir/dom
+ local tmp=$TMP/$tfile
+ trap "cleanup_271def_tests $tmp" EXIT
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt $DIR/$tdir
+
+ local mdtidx=$($GETSTRIPE -M $DIR/$tdir)
+ local facet=mds$((mdtidx + 1))
+
+ cancel_lru_locks mdc
+ dd if=/dev/urandom of=$tmp bs=1000 count=1
+ dd if=$tmp of=$dom bs=1000 count=1
+ cancel_lru_locks mdc
+
+ cat /etc/hosts >> $tmp
+ lctl set_param -n mdc.*.stats=clear
+
+ # append data to the same file it should update local page
+ echo "Append to the same page"
+ cat /etc/hosts >> $dom
+ local num=$(lctl get_param -n mdc.*.stats |
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats |
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats |
+ awk '/req_waittime/ {print $2}')
+
+ [ -z $num ] || error "$num READ RPC occured"
+ [ $ra == $rw ] || error "$((ra - rw)) resend occured"
+ echo "... DONE"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ cancel_lru_locks mdc
+ lctl set_param -n mdc.*.stats=clear
+
+ echo "Open and read file"
+ cat $dom > /dev/null
+ local num=$(lctl get_param -n mdc.*.stats |
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats |
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats |
+ awk '/req_waittime/ {print $2}')
+
+ [ -z $num ] || error "$num READ RPC occured"
+ [ $ra == $rw ] || error "$((ra - rw)) resend occured"
+ echo "... DONE"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ return 0
+}
+run_test 271d "DoM: read on open (1K file in reply buffer)"
+
+test_271e() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.57) ] &&
+ skip "Need MDS version at least 2.10.57" && return
+
+ local dom=$DIR/$tdir/dom
+ local tmp=$TMP/${tfile}.data
+ trap "cleanup_271def_tests $tmp" EXIT
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt $DIR/$tdir
+
+ local mdtidx=$($GETSTRIPE -M $DIR/$tdir)
+ local facet=mds$((mdtidx + 1))
+
+ cancel_lru_locks mdc
+ dd if=/dev/urandom of=$tmp bs=30K count=1
+ dd if=$tmp of=$dom bs=30K count=1
+ cancel_lru_locks mdc
+ cat /etc/hosts >> $tmp
+ lctl set_param -n mdc.*.stats=clear
+
+ echo "Append to the same page"
+ cat /etc/hosts >> $dom
+
+ local num=$(lctl get_param -n mdc.*.stats | \
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_waittime/ {print $2}')
+
+ [ -z $num ] || error "$num READ RPC occured"
+ # Reply buffer can be adjusted for larger buffer by resend
+ echo "... DONE with $((ra - rw)) resends"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ cancel_lru_locks mdc
+ lctl set_param -n mdc.*.stats=clear
+
+ echo "Open and read file"
+ cat $dom > /dev/null
+ local num=$(lctl get_param -n mdc.*.stats | \
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_waittime/ {print $2}')
+
+ [ -z $num ] || error "$num READ RPC occured"
+ # Reply buffer can be adjusted for larger buffer by resend
+ echo "... DONE with $((ra - rw)) resends"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ return 0
+}
+run_test 271e "DoM: read on open (30K file with reply buffer adjusting)"
+
+test_271f() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.57) ] &&
+ skip "Need MDS version at least 2.10.57" && return
+
+ local dom=$DIR/$tdir/dom
+ local tmp=$TMP/$tfile
+ trap "cleanup_271def_tests $tmp" EXIT
+
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -E 1024K -L mdt $DIR/$tdir
+
+ local mdtidx=$($GETSTRIPE -M $DIR/$tdir)
+ local facet=mds$((mdtidx + 1))
+
+ cancel_lru_locks mdc
+ dd if=/dev/urandom of=$tmp bs=200000 count=1
+ dd if=$tmp of=$dom bs=200000 count=1
+ cancel_lru_locks mdc
+ cat /etc/hosts >> $tmp
+ lctl set_param -n mdc.*.stats=clear
+
+ echo "Append to the same page"
+ cat /etc/hosts >> $dom
+ local num=$(lctl get_param -n mdc.*.stats | \
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_waittime/ {print $2}')
+
+ [ -z $num ] || error "$num READ RPC occured"
+ [ $ra == $rw ] || error "$((ra - rw)) resend occured"
+ echo "... DONE"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ cancel_lru_locks mdc
+ lctl set_param -n mdc.*.stats=clear
+
+ echo "Open and read file"
+ cat $dom > /dev/null
+ local num=$(lctl get_param -n mdc.*.stats | \
+ awk '/ost_read/ {print $2}')
+ local ra=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_active/ {print $2}')
+ local rw=$(lctl get_param -n mdc.*.stats | \
+ awk '/req_waittime/ {print $2}')
+
+ [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
+ [ $ra == $rw ] || error "$((ra - rw)) resend occured"
+ echo "... DONE"
+
+ # compare content
+ cmp $tmp $dom || error "file miscompare"
+
+ return 0
+}
+run_test 271f "DoM: read on open (200K file and read tail)"
+
test_275() {
remote_ost_nodsh && skip "remote OST with nodsh"
[ $(lustre_version_code ost1) -lt $(version_code 2.10.57) ] &&
test_316() {
[ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
- large_xattr_enabled || skip_env "large_xattr disabled"
+ large_xattr_enabled || skip_env "ea_inode feature disabled"
rm -rf $DIR/$tdir/d
mkdir -p $DIR/$tdir/d
}
run_test 316 "lfs mv"
+test_317() {
+ local trunc_sz
+ local grant_blk_size
+
+ if [ "$(facet_fstype $facet)" == "zfs" ]; then
+ skip "LU-10370: no implementation for ZFS" && return
+ fi
+
+ stack_trap "rm -f $DIR/$tfile" EXIT
+ grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
+ awk '/grant_block_size:/ { print $2; exit; }')
+ #
+ # Create File of size 5M. Truncate it to below size's and verify
+ # blocks count.
+ #
+ dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
+ error "Create file : $DIR/$tfile"
+
+ for trunc_sz in 2097152 4097 4000 509 0; do
+ $TRUNCATE $DIR/$tfile $trunc_sz ||
+ error "truncate $tfile to $trunc_sz failed"
+ local sz=$(stat --format=%s $DIR/$tfile)
+ local blk=$(stat --format=%b $DIR/$tfile)
+ local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
+ grant_blk_size) * 8))
+
+ if [[ $blk -ne $trunc_blk ]]; then
+ $(which stat) $DIR/$tfile
+ error "Expected Block $trunc_blk got $blk for $tfile"
+ fi
+
+ $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
+ error "Expected Size $trunc_sz got $sz for $tfile"
+ done
+
+ #
+ # sparse file test
+ # Create file with a hole and write actual two blocks. Block count
+ # must be 16.
+ #
+ dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
+ conv=fsync || error "Create file : $DIR/$tfile"
+
+ # Calculate the final truncate size.
+ trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
+
+ #
+ # truncate to size $trunc_sz bytes. Strip the last block
+ # The block count must drop to 8
+ #
+ $TRUNCATE $DIR/$tfile $trunc_sz ||
+ error "truncate $tfile to $trunc_sz failed"
+
+ local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
+ sz=$(stat --format=%s $DIR/$tfile)
+ blk=$(stat --format=%b $DIR/$tfile)
+
+ if [[ $blk -ne $trunc_bsz ]]; then
+ $(which stat) $DIR/$tfile
+ error "Expected Block $trunc_bsz got $blk for $tfile"
+ fi
+
+ $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
+ error "Expected Size $trunc_sz got $sz for $tfile"
+}
+run_test 317 "Verify blocks get correctly update after truncate"
+
test_fake_rw() {
local read_write=$1
if [ "$read_write" = "write" ]; then
}
run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
+test_415() {
+ [ $PARALLEL == "yes" ] && skip "skip parallel run"
+ [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
+ skip "Need server version at least 2.11.52"
+
+ # LU-11102
+ local total
+ local setattr_pid
+ local start_time
+ local end_time
+ local duration
+
+ total=500
+ # this test may be slow on ZFS
+ [ "$(facet_fstype mds1)" == "zfs" ] && total=100
+
+ # though this test is designed for striped directory, let's test normal
+ # directory too since lock is always saved as CoS lock.
+ test_mkdir $DIR/$tdir || error "mkdir $tdir"
+ createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
+
+ (
+ while true; do
+ touch $DIR/$tdir
+ done
+ ) &
+ setattr_pid=$!
+
+ start_time=$(date +%s)
+ for i in $(seq $total); do
+ mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
+ > /dev/null
+ done
+ end_time=$(date +%s)
+ duration=$((end_time - start_time))
+
+ kill -9 $setattr_pid
+
+ echo "rename $total files took $duration sec"
+ [ $duration -lt 100 ] || error "rename took $duration sec"
+}
+run_test 415 "lock revoke is not missing"
+
prep_801() {
[[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
[[ $(lustre_version_code ost1) -lt $(version_code 2.9.55) ]] &&
[[ $(lustre_version_code ost1) -lt $(version_code 2.9.55) ]] &&
skip "Need server version at least 2.9.55"
+ [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
+
mkdir $DIR/$tdir || error "(1) fail to mkdir"
cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
}
run_test 805 "ZFS can remove from full fs"
+# Size-on-MDS test
+check_lsom_data()
+{
+ local file=$1
+ local size=$($LFS getsom -s $file)
+ local expect=$(stat -c %s $file)
+
+ [[ $size == $expect ]] ||
+ error "$file expected size: $expect, got: $size"
+
+ local blocks=$($LFS getsom -b $file)
+ expect=$(stat -c %b $file)
+ [[ $blocks == $expect ]] ||
+ error "$file expected blocks: $expect, got: $blocks"
+}
+
+check_lsom_size()
+{
+ local size=$($LFS getsom -s $1)
+ local expect=$2
+
+ [[ $size == $expect ]] ||
+ error "$file expected size: $expect, got: $size"
+}
+
+test_806() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.52) ] &&
+ skip "Need MDS version at least 2.11.52" && return
+
+ local bs=1048576
+
+ touch $DIR/$tfile || error "touch $tfile failed"
+
+ local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
+ save_lustre_params client "llite.*.xattr_cache" > $save
+ lctl set_param llite.*.xattr_cache=0
+ stack_trap "restore_lustre_params < $save" EXIT
+
+ # single-threaded write
+ echo "Test SOM for single-threaded write"
+ dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
+ error "write $tfile failed"
+ check_lsom_size $DIR/$tfile $bs
+
+ local num=32
+ local size=$(($num * $bs))
+ local offset=0
+ local i
+
+ echo "Test SOM for single client muti-threaded($num) write"
+ $TRUNCATE $DIR/$tfile 0
+ for ((i = 0; i < $num; i++)); do
+ $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
+ local pids[$i]=$!
+ offset=$((offset + $bs))
+ done
+ for (( i=0; i < $num; i++ )); do
+ wait ${pids[$i]}
+ done
+ check_lsom_size $DIR/$tfile $size
+
+ $TRUNCATE $DIR/$tfile 0
+ for ((i = 0; i < $num; i++)); do
+ offset=$((offset - $bs))
+ $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
+ local pids[$i]=$!
+ done
+ for (( i=0; i < $num; i++ )); do
+ wait ${pids[$i]}
+ done
+ check_lsom_size $DIR/$tfile $size
+
+ # multi-client wirtes
+ num=$(get_node_count ${CLIENTS//,/ })
+ size=$(($num * $bs))
+ offset=0
+ i=0
+
+ echo "Test SOM for muti-client ($num) writes"
+ $TRUNCATE $DIR/$tfile 0
+ for client in ${CLIENTS//,/ }; do
+ do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
+ local pids[$i]=$!
+ i=$((i + 1))
+ offset=$((offset + $bs))
+ done
+ for (( i=0; i < $num; i++ )); do
+ wait ${pids[$i]}
+ done
+ check_lsom_size $DIR/$tfile $offset
+
+ i=0
+ $TRUNCATE $DIR/$tfile 0
+ for client in ${CLIENTS//,/ }; do
+ offset=$((offset - $bs))
+ do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
+ local pids[$i]=$!
+ i=$((i + 1))
+ done
+ for (( i=0; i < $num; i++ )); do
+ wait ${pids[$i]}
+ done
+ check_lsom_size $DIR/$tfile $size
+
+ # verify truncate
+ echo "Test SOM for truncate"
+ $TRUNCATE $DIR/$tfile 1048576
+ check_lsom_size $DIR/$tfile 1048576
+ $TRUNCATE $DIR/$tfile 1234
+ check_lsom_size $DIR/$tfile 1234
+
+ # verify SOM blocks count
+ echo "Verify SOM block count"
+ $TRUNCATE $DIR/$tfile 0
+ $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
+ error "failed to write file $tfile"
+ check_lsom_data $DIR/$tfile
+}
+run_test 806 "Verify Lazy Size on MDS"
+
+test_807() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.52) ] &&
+ skip "Need MDS version at least 2.11.52" && return
+
+ # Registration step
+ changelog_register || error "changelog_register failed"
+ local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
+ changelog_users $SINGLEMDS | grep -q $cl_user ||
+ error "User $cl_user not found in changelog_users"
+
+ local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
+ save_lustre_params client "llite.*.xattr_cache" > $save
+ lctl set_param llite.*.xattr_cache=0
+ stack_trap "restore_lustre_params < $save" EXIT
+
+ rm -rf $DIR/$tdir || error "rm $tdir failed"
+ mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
+ touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
+ $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
+ $TRUNCATE $DIR/$tdir/trunc 1048576 ||
+ error "truncate $tdir/trunc failed"
+
+ local bs=1048576
+ dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
+ error "write $tfile failed"
+
+ # multi-client wirtes
+ local num=$(get_node_count ${CLIENTS//,/ })
+ local offset=0
+ local i=0
+
+ echo "Test SOM for muti-client ($num) writes"
+ touch $DIR/$tfile || error "touch $tfile failed"
+ $TRUNCATE $DIR/$tfile 0
+ for client in ${CLIENTS//,/ }; do
+ do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
+ local pids[$i]=$!
+ i=$((i + 1))
+ offset=$((offset + $bs))
+ done
+ for (( i=0; i < $num; i++ )); do
+ wait ${pids[$i]}
+ done
+
+ sleep 5
+ $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
+ check_lsom_data $DIR/$tdir/trunc
+ check_lsom_data $DIR/$tdir/single_dd
+ check_lsom_data $DIR/$tfile
+
+ rm -rf $DIR/$tdir
+ # Deregistration step
+ changelog_deregister || error "changelog_deregister failed"
+}
+run_test 807 "verify LSOM syncing tool"
+
#
# tests that do cleanup/setup should be run at the end
#