ALWAYS_EXCEPT=" 27u 42a 42b 42c 42d 45 51d 68b $SANITY_EXCEPT"
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
+# with LOD/OSP landing
+# bug number for skipped tests: LU2036
+ALWAYS_EXCEPT=" 76 $ALWAYS_EXCEPT"
+
+
# Tests that fail on uml
CPU=`awk '/model/ {print $4}' /proc/cpuinfo`
# buffer i/o errs sock spc runas
}
run_test 17k "symlinks: rsync with xattrs enabled ========================="
+# LU-1540
+test_17m() {
+ local short_sym="0123456789"
+ local WDIR=$DIR/${tdir}m
+ local mds_index
+ local devname
+ local cmd
+ local i
+ local rc=0
+
+ [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.0) ] &&
+ [ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.2.93) ] &&
+ skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks" && return
+
+ [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
+ skip "only for ldiskfs MDT" && return 0
+
+ mkdir -p $WDIR
+ long_sym=$short_sym
+ # create a long symlink file
+ for ((i = 0; i < 4; ++i)); do
+ long_sym=${long_sym}${long_sym}
+ done
+
+ echo "create 512 short and long symlink files under $WDIR"
+ for ((i = 0; i < 256; ++i)); do
+ ln -sf ${long_sym}"a5a5" $WDIR/long-$i
+ ln -sf ${short_sym}"a5a5" $WDIR/short-$i
+ done
+
+ echo "erase them"
+ rm -f $WDIR/*
+ sync
+ sleep 2
+
+ echo "recreate the 512 symlink files with a shorter string"
+ for ((i = 0; i < 512; ++i)); do
+ # rewrite the symlink file with a shorter string
+ ln -sf ${long_sym} $WDIR/long-$i
+ ln -sf ${short_sym} $WDIR/short-$i
+ done
+
+ mds_index=$($LFS getstripe -M $WDIR)
+ mds_index=$((mds_index+1))
+ devname=$(mdsdevname $mds_index)
+ cmd="$E2FSCK -fnvd $devname"
+
+ echo "stop and checking mds${mds_index}: $cmd"
+ # e2fsck should not return error
+ stop mds${mds_index} -f
+ do_facet mds${mds_index} $cmd || rc=$?
+
+ start mds${mds_index} $devname $MDS_MOUNT_OPTS
+ df $MOUNT > /dev/null 2>&1
+ [ $rc -ne 0 ] && error "e2fsck should not report error upon "\
+ "short/long symlink MDT: rc=$rc"
+ return $rc
+}
+run_test 17m "run e2fsck against MDT which contains short/long symlink"
+
test_18() {
touch $DIR/f
ls $DIR || error
[ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
do_nodes $list lctl set_param fail_loc=0
+ sync # initiate all OST_DESTROYs from MDS to OST
sleep_maxage
}
# this should be set to future
TEST_39_ATIME=`date -d "1 year" +%s`
+is_sles11() # LU-1783
+{
+ if [ -r /etc/SuSE-release ]
+ then
+ local vers=`grep VERSION /etc/SuSE-release | awk '{print $3}'`
+ local patchlev=`grep PATCHLEVEL /etc/SuSE-release \
+ | awk '{print $3}'`
+ if [ $vers -eq 11 ] && [ $patchlev -eq 1 ]
+ then
+ return 0
+ fi
+ fi
+ return 1
+}
+
test_39l() {
+ is_sles11 && skip "SLES 11 SP1" && return # LU-1783
remote_mds_nodsh && skip "remote MDS with nodsh" && return
local atime_diff=$(do_facet $SINGLEMDS lctl get_param -n mdd.*.atime_diff)
local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
local orig_mppc=`$LCTL get_param -n $osc1_mppc`
# loop until dd process exits
- while ps ax -opid | grep -q $dd_pid; do
+ while ps ax -opid | grep -wq $dd_pid; do
$LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
sleep $((RANDOM % 5 + 1))
done
export NUMTEST=70000
test_51b() {
- NUMFREE=`df -i -P $DIR | tail -n 1 | awk '{ print $4 }'`
- [ $NUMFREE -lt 21000 ] && \
- skip "not enough free inodes ($NUMFREE)" && \
+ local BASE=$DIR/$tdir
+ mkdir -p $BASE
+
+ local mdtidx=$(printf "%04x" $($LFS getstripe -M $BASE))
+ local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
+ [ $numfree -lt 21000 ] && skip "not enough free inodes ($numfree)" &&
return
- [ $NUMFREE -lt $NUMTEST ] && NUMTEST=$(($NUMFREE - 50))
+ [ $numfree -lt $NUMTEST ] && NUMTEST=$(($numfree - 50)) &&
+ echo "reduced count to $NUMTEST due to inodes"
- mkdir -p $DIR/d51b
- createmany -d $DIR/d51b/t- $NUMTEST
+ # need to check free space for the directories as well
+ local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
+ numfree=$((blkfree / 4))
+ [ $numfree -lt $NUMTEST ] && NUMTEST=$(($numfree - 50)) &&
+ echo "reduced count to $NUMTEST due to blocks"
+
+ createmany -d $BASE/d $NUMTEST && echo $NUMTEST > $BASE/fnum ||
+ echo "failed" > $BASE/fnum
}
-run_test 51b "mkdir .../t-0 --- .../t-$NUMTEST ===================="
+run_test 51b "exceed 64k subdirectory nlink limit"
test_51ba() { # LU-993
- local BASE=$DIR/d51b
- # unlink all but 100 subdirectories, then check it still works
- local LEFT=100
- local DELETE=$((NUMTEST - LEFT))
-
- ! [ -d "${BASE}/t-$DELETE" ] && skip "test_51b() not run" && return 0
+ local BASE=$DIR/$tdir
+ # unlink all but 100 subdirectories, then check it still works
+ local LEFT=100
+ [ -f $BASE/fnum ] && local NUMPREV=$(cat $BASE/fnum) && rm $BASE/fnum
+
+ [ "$NUMPREV" != "failed" ] && NUMTEST=$NUMPREV
+ local DELETE=$((NUMTEST - LEFT))
+
+ # continue on to run this test even if 51b didn't finish,
+ # just to delete the many subdirectories created.
+ [ ! -d "${BASE}/d1" ] && skip "test_51b() not run" && return 0
+
+ # for ldiskfs the nlink count should be 1, but this is OSD specific
+ # and so this is listed for informational purposes only
+ echo "nlink before: $(stat -c %h $BASE), created before: $NUMTEST"
+ unlinkmany -d $BASE/d $DELETE
+ RC=$?
- # for ldiskfs the nlink count should be 1, but this is OSD specific
- # and so this is listed for informational purposes only
- log "nlink before: $(stat -c %h $BASE)"
- unlinkmany -d $BASE/t- $DELETE ||
- error "unlink of first $DELETE subdirs failed"
+ if [ $RC -ne 0 ]; then
+ if [ "$NUMPREV" == "failed" ]; then
+ skip "previous setup failed"
+ return 0
+ else
+ error "unlink of first $DELETE subdirs failed"
+ return $RC
+ fi
+ fi
- log "nlink between: $(stat -c %h $BASE)"
- local FOUND=$(ls -l ${BASE} | wc -l)
- FOUND=$((FOUND - 1)) # trim the first line of ls output
- [ $FOUND -ne $LEFT ] &&
- error "can't find subdirs: found only $FOUND/$LEFT"
+ echo "nlink between: $(stat -c %h $BASE)"
+ # trim the first line of ls output
+ local FOUND=$(($(ls -l ${BASE} | wc -l) - 1))
+ [ $FOUND -ne $LEFT ] &&
+ error "can't find subdirs: found only $FOUND/$LEFT"
- unlinkmany -d $BASE/t- $DELETE $LEFT ||
- error "unlink of second $LEFT subdirs failed"
- log "nlink after: $(stat -c %h $BASE)"
+ unlinkmany -d $BASE/d $DELETE $LEFT ||
+ error "unlink of second $LEFT subdirs failed"
+ # regardless of whether the backing filesystem tracks nlink accurately
+ # or not, the nlink count shouldn't be more than "." and ".." here
+ local AFTER=$(stat -c %h $BASE)
+ [ $AFTER -gt 2 ] && error "nlink after: $AFTER > 2" ||
+ echo "nlink after: $AFTER"
}
-run_test 51ba "rmdir .../t-0 --- .../t-$NUMTEST"
+run_test 51ba "verify nlink for many subdirectory cleanup"
test_51bb() {
[ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
test_57a() {
# note test will not do anything if MDS is not local
+ if [ "$(facet_type_fstype MDS)" != ldiskfs ]; then
+ skip "Only applicable to ldiskfs-based MDTs"
+ return
+ fi
+
remote_mds_nodsh && skip "remote MDS with nodsh" && return
local MNTDEV="osd*.*MDT*.mntdev"
DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
run_test 57a "verify MDS filesystem created with large inodes =="
test_57b() {
+ if [ "$(facet_type_fstype MDS)" != ldiskfs ]; then
+ skip "Only applicable to ldiskfs-based MDTs"
+ return
+ fi
+
remote_mds_nodsh && skip "remote MDS with nodsh" && return
local dir=$DIR/d57b
run_test 65ib "getstripe -v on -1 default directory striping"
test_65ic() { # bug12836
- $LFS find -mtime -1 $MOUNT || error "find $MOUNT failed"
+ $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
}
run_test 65ic "new find on -1 default directory striping"
test_66() {
COUNT=${COUNT:-8}
dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
- sync; sleep 1; sync
+ sync; sync_all_data; sync; sync_all_data
+ cancel_lru_locks osc
BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
[ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
}
run_test 79 "df report consistency check ======================="
test_80() { # bug 10718
+ # relax strong synchronous semantics for slow backends like ZFS
+ local soc="obdfilter.*.sync_on_lock_cancel"
+ local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
+ local hosts=
+ if [ "$soc_old" != "never" -a "$FSTYPE" != "ldiskfs" ]; then
+ hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
+ facet_active_host $host; done | sort -u)
+ do_nodes $hosts lctl set_param $soc=never
+ fi
+
dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
sync; sleep 1; sync
local BEFORE=`date +%s`
if [ $DIFF -gt 1 ] ; then
error "elapsed for 1M@1T = $DIFF"
fi
+
+ [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
+
true
rm -f $DIR/$tfile
}
remote_ost_nodsh && skip "remote OST with nodsh" && return
# define OBD_FAIL_OST_MAPBLK_ENOSPC 0x228
# MUST OR with the OBD_FAIL_ONCE (0x80000000)
- do_facet ost0 lctl set_param fail_loc=0x80000228
+ do_facet ost1 lctl set_param fail_loc=0x80000228
# write should trigger a retry and success
$SETSTRIPE -i 0 -c 1 $DIR/$tfile
remote_ost_nodsh && skip "remote OST with nodsh" && return
# define OBD_FAIL_OST_MAPBLK_ENOSPC 0x228
# Don't OR with the OBD_FAIL_ONCE (0x80000000)
- do_facet ost0 lctl set_param fail_loc=0x228
+ do_facet ost1 lctl set_param fail_loc=0x228
# write should retry several times and return -ENOSPC finally
$SETSTRIPE -i 0 -c 1 $DIR/$tfile
echo read-ahead disabled time read $time_ra_OFF
echo read-ahead enabled time read $time_ra_ON
- set_read_ahead $old_READAHEAD
- rm -f $file
+ set_read_ahead $old_READAHEAD
+ rm -f $file
+ wait_delete_completed
[ $time_ra_ON -lt $time_ra_OFF ] ||
error "read-ahead enabled time read (${time_ra_ON}s) is more than
cut -c11-20)
# don't return an error
- [ $OSTIO_post -eq $OSTIO_pre ] && echo \
- "WARNING: No new ll_ost_io threads were created ($OSTIO_pre)" &&\
- echo "This may be fine, depending on what ran before this test" &&\
+ [ $OSTIO_post == $OSTIO_pre ] && echo \
+ "WARNING: No new ll_ost_io threads were created ($OSTIO_pre)" &&
+ echo "This may be fine, depending on what ran before this test" &&
echo "and how fast this system is." && return
echo "Started with $OSTIO_pre threads, ended with $OSTIO_post"
echo Max free space: OST $MAXI: $MAXV
}
-test_116() {
+test_116a() { # was previously test_116()
[ "$OSTCOUNT" -lt "2" ] && skip_env "$OSTCOUNT < 2 OSTs" && return
echo -n "Free space priority "
rm -rf $DIR/$tdir
}
-run_test 116 "stripe QOS: free space balance ==================="
+run_test 116a "stripe QOS: free space balance ==================="
+
+test_116b() { # LU-2093
+#define OBD_FAIL_MDS_OSC_CREATE_FAIL 0x147
+ local old_rr
+ old_rr=$(do_facet $SINGLEMDS lctl get_param -n lov.*mdtlov*.qos_threshold_rr)
+ do_facet $SINGLEMDS lctl set_param lov.*mdtlov*.qos_threshold_rr 0
+ mkdir -p $DIR/$tdir
+ do_facet $SINGLEMDS lctl set_param fail_loc=0x147
+ createmany -o $DIR/$tdir/f- 20 || error "can't create"
+ do_facet $SINGLEMDS lctl set_param fail_loc=0
+ rm -rf $DIR/$tdir
+ do_facet $SINGLEMDS lctl set_param lov.*mdtlov*.qos_threshold_rr $old_rr
+}
+run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
test_117() # bug 10891
{
}
run_test 118h "Verify timeout in handling recoverables errors =========="
+[ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
+
test_118i() {
remote_ost_nodsh && skip "remote OST with nodsh" && return
}
run_test 118i "Fix error before timeout in recoverable error =========="
+[ "$SLOW" = "no" ] && set_resend_count 4
+
test_118j() {
remote_ost_nodsh && skip "remote OST with nodsh" && return
}
test_130a() {
- filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
- [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+ local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP" &&
+ return
trap cleanup_130 EXIT RETURN
local fm_file=$DIR/$tfile
$SETSTRIPE -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
- dd if=/dev/zero of=$fm_file bs=65536 count=1 || error "dd failed for $fm_file"
+ dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
+ error "dd failed for $fm_file"
- filefrag -ves $fm_file || error "filefrag $fm_file failed"
- filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+ # LU-1795: test filefrag/FIEMAP once, even if unsupported
+ filefrag -ves $fm_file
+ RC=$?
+ [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
+ skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
+ [ $RC != 0 ] && error "filefrag $fm_file failed"
+ filefrag_op=$(filefrag -ve $fm_file | grep -A 100 "ext:" |
+ grep -v "ext:" | grep -v "found")
lun=$($GETSTRIPE -i $fm_file)
start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
run_test 130a "FIEMAP (1-stripe file)"
test_130b() {
- [ "$OSTCOUNT" -lt "2" ] && skip_env "skipping FIEMAP on 2-stripe file test" && return
+ [ "$OSTCOUNT" -lt "2" ] &&
+ skip_env "skipping FIEMAP on 2-stripe file test" && return
- filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
- [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+ local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP" &&
+ return
trap cleanup_130 EXIT RETURN
local fm_file=$DIR/$tfile
$SETSTRIPE -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
- dd if=/dev/zero of=$fm_file bs=1M count=2 || error "dd failed on $fm_file"
+ [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
+ skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
+
+ dd if=/dev/zero of=$fm_file bs=1M count=2 ||
+ error "dd failed on $fm_file"
filefrag -ves $fm_file || error "filefrag $fm_file failed"
- filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+ filefrag_op=$(filefrag -ve $fm_file | grep -A 100 "ext:" |
+ grep -v "ext:" | grep -v "found")
- last_lun=`echo $filefrag_op | cut -d: -f5`
+ last_lun=$(echo $filefrag_op | cut -d: -f5)
IFS=$'\n'
tot_len=0
run_test 130b "FIEMAP (2-stripe file)"
test_130c() {
- [ "$OSTCOUNT" -lt "2" ] && skip_env "skipping FIEMAP on 2-stripe file with hole test" && return
+ [ "$OSTCOUNT" -lt "2" ] &&
+ skip_env "skipping FIEMAP on 2-stripe file" && return
filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
- [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" &&
+ return
trap cleanup_130 EXIT RETURN
local fm_file=$DIR/$tfile
$SETSTRIPE -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
+ [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
+ skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
+
dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 || error "dd failed on $fm_file"
filefrag -ves $fm_file || error "filefrag $fm_file failed"
local fm_file=$DIR/$tfile
$SETSTRIPE -S 65536 -c $OSTCOUNT $fm_file||error "setstripe on $fm_file"
+ [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
+ skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT || error "dd failed on $fm_file"
filefrag -ves $fm_file || error "filefrag $fm_file failed"
local fm_file=$DIR/$tfile
$SETSTRIPE -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
+ [ "$(facet_fstype ost$(($($GETSTRIPE -i $fm_file) + 1)))" = "zfs" ] &&
+ skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" && return
+
NUM_BLKS=512
EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
for ((i = 0; i < $NUM_BLKS; i++))
chmod 444 ${testdir}/${tfile} || error "chmod failed"
check_stats $SINGLEMDS "setattr" 1
do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
- ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
- check_stats $SINGLEMDS "getattr" 1
+ if [ $(lustre_version_code $SINGLEMDS) -ne $(version_code 2.2.0) ]
+ then # LU-1740
+ ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
+ check_stats $SINGLEMDS "getattr" 1
+ fi
$LFS df || error "lfs failed"
check_stats $SINGLEMDS "statfs" 1
$SETSTRIPE -c 1 -i 0 ${testdir}/${tfile}
sync
cancel_lru_locks osc
+ wait_delete_completed
# clear stats.
do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
check_stats ost "punch" 1
rm -f ${testdir}/${tfile} || error "file remove failed"
+ wait_delete_completed
check_stats ost "destroy" 1
rm -rf $DIR/${tdir}
run_test 150 "truncate/append tests"
function roc_hit() {
- local list=$(comma_list $(osts_nodes))
+ local list=$(comma_list $(osts_nodes))
- ACCNUM=$(do_nodes $list $LCTL get_param -n obdfilter.*.stats | \
- awk '/'cache_hit'/ {sum+=$2} END {print sum}')
- echo $ACCNUM
+ echo $(get_obdfilter_param $list '' stats |
+ awk '/'cache_hit'/ {sum+=$2} END {print sum}')
}
function set_cache() {
- local on=1
+ local on=1
- if [ "$2" == "off" ]; then
- on=0;
- fi
- local list=$(comma_list $(osts_nodes))
- do_nodes $list lctl set_param obdfilter.*.${1}_cache_enable $on
+ if [ "$2" == "off" ]; then
+ on=0;
+ fi
+ local list=$(comma_list $(osts_nodes))
+ set_obdfilter_param $list '' $1_cache_enable $on
- cancel_lru_locks osc
+ cancel_lru_locks osc
}
test_151() {
- remote_ost_nodsh && skip "remote OST with nodsh" && return
+ remote_ost_nodsh && skip "remote OST with nodsh" && return
- local CPAGES=3
- local list=$(comma_list $(osts_nodes))
+ local CPAGES=3
+ local list=$(comma_list $(osts_nodes))
- # check whether obdfilter is cache capable at all
- if ! do_nodes $list $LCTL get_param -n obdfilter.*.read_cache_enable > /dev/null; then
- echo "not cache-capable obdfilter"
- return 0
- fi
+ # check whether obdfilter is cache capable at all
+ if ! get_obdfilter_param $list '' read_cache_enable >/dev/null; then
+ echo "not cache-capable obdfilter"
+ return 0
+ fi
- # check cache is enabled on all obdfilters
- if do_nodes $list $LCTL get_param -n obdfilter.*.read_cache_enable | grep 0 >&/dev/null; then
- echo "oss cache is disabled"
- return 0
- fi
+ # check cache is enabled on all obdfilters
+ if get_obdfilter_param $list '' read_cache_enable | grep 0; then
+ echo "oss cache is disabled"
+ return 0
+ fi
- do_nodes $list $LCTL set_param -n obdfilter.*.writethrough_cache_enable 1
+ set_obdfilter_param $list '' writethrough_cache_enable 1
# pages should be in the case right after write
dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES || error "dd failed"
# the following read invalidates the cache
cancel_lru_locks osc
- do_nodes $list $LCTL set_param -n obdfilter.*.read_cache_enable 0
+ set_obdfilter_param $list '' read_cache_enable 0
cat $DIR/$tfile >/dev/null
# now data shouldn't be found in the cache
error "IN CACHE: before: $BEFORE, after: $AFTER"
fi
- do_nodes $list $LCTL set_param -n obdfilter.*.read_cache_enable 1
+ set_obdfilter_param $list '' read_cache_enable 1
rm -f $DIR/$tfile
}
run_test 151 "test cache on oss and controls ==============================="
run_test 153 "test if fdatasync does not crash ======================="
test_154() {
+ [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ]] ||
+ { skip "Need MDS version at least 2.2.51"; return 0; }
+
cp /etc/hosts $DIR/$tfile
fid=$($LFS path2fid $DIR/$tfile)
touch $DIR/.lustre/fid/$tfile && \
error "touch $DIR/.lustre/fid/$tfile should fail."
+ echo "setxattr to $DIR/.lustre/fid"
+ setfattr -n trusted.name1 -v value1 $DIR/.lustre/fid &&
+ error "setxattr should fail."
+
+ echo "listxattr for $DIR/.lustre/fid"
+ getfattr -d -m "^trusted" $DIR/.lustre/fid &&
+ error "listxattr should fail."
+
+ echo "delxattr from $DIR/.lustre/fid"
+ setfattr -x trusted.name1 $DIR/.lustre/fid &&
+ error "delxattr should fail."
+
+ echo "touch invalid fid: $DIR/.lustre/fid/[0x200000400:0x2:0x3]"
+ touch $DIR/.lustre/fid/[0x200000400:0x2:0x3] &&
+ error "touch invalid fid should fail."
+
+ echo "touch non-normal fid: $DIR/.lustre/fid/[0x1:0x2:0x0]"
+ touch $DIR/.lustre/fid/[0x1:0x2:0x0] &&
+ error "touch non-normal fid should fail."
+
+ echo "rename $tdir to $DIR/.lustre/fid"
+ mrename $DIR/$tdir $DIR/.lustre/fid &&
+ error "rename to $DIR/.lustre/fid should fail."
+
+ echo "rename .lustre to itself"
+ fid=$($LFS path2fid $DIR)
+ mrename $DIR/.lustre $DIR/.lustre/fid/$fid/.lustre &&
+ error "rename .lustre to itself should fail."
+
+ $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $DIR/$tfile-2
+ fid=$($LFS path2fid $DIR/$tfile-2)
+ echo "cp /etc/passwd $DIR/.lustre/fid/$fid"
+ cp /etc/passwd $DIR/.lustre/fid/$fid &&
+ error "create lov data thru .lustre should fail."
+ echo "cp /etc/passwd $DIR/$tfile-2"
+ cp /etc/passwd $DIR/$tfile-2 || error "copy to $DIR/$tfile-2 failed."
+ echo "diff /etc/passwd $DIR/.lustre/fid/$fid"
+ diff /etc/passwd $DIR/.lustre/fid/$fid ||
+ error "diff /etc/passwd $DIR/.lustre/fid/$fid failed."
+
echo "Open-by-FID succeeded"
}
run_test 154 "Open-by-FID"
run_test 182 "Disable MDC RPCs semaphore wouldn't crash client ================"
# OST pools tests
-POOL=${POOL:-cea1}
-TGT_COUNT=$OSTCOUNT
-TGTPOOL_FIRST=1
-TGTPOOL_MAX=$(($TGT_COUNT - 1))
-TGTPOOL_STEP=2
-TGTPOOL_LIST=`seq $TGTPOOL_FIRST $TGTPOOL_STEP $TGTPOOL_MAX`
-POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
-POOL_DIR_NAME=dir_tst
-POOL_DIR=$POOL_ROOT/$POOL_DIR_NAME
-POOL_FILE=$POOL_ROOT/file_tst
-
check_file_in_pool()
{
- file=$1
- res=$($GETSTRIPE $file | grep 0x | cut -f2)
+ local file=$1
+ local pool=$2
+ local tlist="$3"
+ local res=$($GETSTRIPE $file | grep 0x | cut -f2)
for i in $res
do
- found=$(echo :$TGTPOOL_LIST: | tr " " ":" | grep :$i:)
- if [[ "$found" == "" ]]
- then
- echo "pool list: $TGTPOOL_LIST"
- echo "striping: $res"
- error "$file not allocated in $POOL"
- return 1
- fi
+ for t in $tlist ; do
+ [ "$i" -eq "$t" ] && continue 2
+ done
+
+ echo "pool list: $tlist"
+ echo "striping: $res"
+ error_noexit "$file not allocated in $pool"
+ return 1
done
return 0
}
-trap "cleanup_pools $FSNAME" EXIT
+pool_add() {
+ echo "Creating new pool"
+ local pool=$1
-test_200a() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- create_pool $FSNAME.$POOL || return $?
- [ $($LFS pool_list $FSNAME | grep -c $POOL) -eq 1 ] ||
- error "$POOL not in lfs pool_list"
+ create_pool $FSNAME.$pool ||
+ { error_noexit "No pool created, result code $?"; return 1; }
+ [ $($LFS pool_list $FSNAME | grep -c $pool) -eq 1 ] ||
+ { error_noexit "$pool not in lfs pool_list"; return 2; }
}
-run_test 200a "Create new pool =========================================="
-test_200b() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- TGT=$(for i in $TGTPOOL_LIST; do printf "$FSNAME-OST%04x_UUID " $i; done)
- do_facet mgs $LCTL pool_add $FSNAME.$POOL \
- $FSNAME-OST[$TGTPOOL_FIRST-$TGTPOOL_MAX/$TGTPOOL_STEP]
- wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | sort -u | tr '\n' ' ' " "$TGT" ||
- error "Add to pool failed"
- local lfscount=$($LFS pool_list $FSNAME.$POOL | grep -c "\-OST")
- local addcount=$((($TGTPOOL_MAX - $TGTPOOL_FIRST) / $TGTPOOL_STEP + 1))
- [ $lfscount -eq $addcount ] ||
- error "lfs pool_list bad ost count $lfscount != $addcount"
-}
-run_test 200b "Add targets to a pool ===================================="
-
-test_200c() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- mkdir -p $POOL_DIR
- $SETSTRIPE -c 2 -p $POOL $POOL_DIR
- [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR"
- # b-19919 test relative path works well
- mkdir -p $POOL_DIR/$POOL_DIR_NAME
- cd $POOL_DIR
- $SETSTRIPE -c 2 -p $POOL $POOL_DIR_NAME
- [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR/$POOL_DIR_NAME"
- $SETSTRIPE -c 2 -p $POOL ./$POOL_DIR_NAME
- [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR/./$POOL_DIR_NAME"
- $SETSTRIPE -c 2 -p $POOL ../$POOL_DIR_NAME
- [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR/../$POOL_DIR_NAME"
- $SETSTRIPE -c 2 -p $POOL ../$POOL_DIR_NAME/$POOL_DIR_NAME
- [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR/../$POOL_DIR_NAME/$POOL_DIR_NAME"
- rm -rf $POOL_DIR_NAME; cd -
-}
-run_test 200c "Set pool on a directory ================================="
-
-test_200d() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- res=$($GETSTRIPE --pool $POOL_DIR)
- [ $res = $POOL ] || error "Pool on $POOL_DIR is $res, not $POOL"
+pool_add_targets() {
+ echo "Adding targets to pool"
+ local pool=$1
+ local first=$2
+ local last=$3
+ local step=${4:-1}
+
+ local list=$(seq $first $step $last)
+
+ local t=$(for i in $list; do printf "$FSNAME-OST%04x_UUID " $i; done)
+ do_facet mgs $LCTL pool_add \
+ $FSNAME.$pool $FSNAME-OST[$first-$last/$step]
+ wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool \
+ | sort -u | tr '\n' ' ' " "$t" || {
+ error_noexit "Add to pool failed"
+ return 1
+ }
+ local lfscount=$($LFS pool_list $FSNAME.$pool | grep -c "\-OST")
+ local addcount=$(((last - first) / step + 1))
+ [ $lfscount -eq $addcount ] || {
+ error_noexit "lfs pool_list bad ost count" \
+ "$lfscount != $addcount"
+ return 2
+ }
}
-run_test 200d "Check pool on a directory ==============================="
-test_200e() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- failed=0
- for i in $(seq -w 1 $(($TGT_COUNT * 3)))
+pool_set_dir() {
+ local pool=$1
+ local tdir=$2
+ echo "Setting pool on directory $tdir"
+
+ $SETSTRIPE -c 2 -p $pool $tdir && return 0
+
+ error_noexit "Cannot set pool $pool to $tdir"
+ return 1
+}
+
+pool_check_dir() {
+ local pool=$1
+ local tdir=$2
+ echo "Checking pool on directory $tdir"
+
+ local res=$($GETSTRIPE --pool $tdir | sed "s/\s*$//")
+ [ "$res" = "$pool" ] && return 0
+
+ error_noexit "Pool on '$tdir' is '$res', not '$pool'"
+ return 1
+}
+
+pool_dir_rel_path() {
+ echo "Testing relative path works well"
+ local pool=$1
+ local tdir=$2
+ local root=$3
+
+ mkdir -p $root/$tdir/$tdir
+ cd $root/$tdir
+ pool_set_dir $pool $tdir || return 1
+ pool_set_dir $pool ./$tdir || return 2
+ pool_set_dir $pool ../$tdir || return 3
+ pool_set_dir $pool ../$tdir/$tdir || return 4
+ rm -rf $tdir; cd - > /dev/null
+}
+
+pool_alloc_files() {
+ echo "Checking files allocation from directory pool"
+ local pool=$1
+ local tdir=$2
+ local count=$3
+ local tlist="$4"
+
+ local failed=0
+ for i in $(seq -w 1 $count)
do
- file=$POOL_DIR/file-$i
+ local file=$tdir/file-$i
touch $file
- check_file_in_pool $file
- if [[ $? != 0 ]]
- then
- failed=$(($failed + 1))
- fi
+ check_file_in_pool $file $pool "$tlist" || \
+ failed=$((failed + 1))
done
- [ "$failed" = 0 ] || error "$failed files not allocated in $POOL"
+ [ "$failed" = 0 ] && return 0
+
+ error_noexit "$failed files not allocated in $pool"
+ return 1
}
-run_test 200e "Check files allocation from directory pool =============="
-test_200f() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- mkdir -p $POOL_FILE
- failed=0
- for i in $(seq -w 1 $(($TGT_COUNT * 3)))
+pool_create_files() {
+ echo "Creating files in pool"
+ local pool=$1
+ local tdir=$2
+ local count=$3
+ local tlist="$4"
+
+ mkdir -p $tdir
+ local failed=0
+ for i in $(seq -w 1 $count)
do
- file=$POOL_FILE/spoo-$i
- $SETSTRIPE -p $POOL $file
- check_file_in_pool $file
- if [[ $? != 0 ]]
- then
- failed=$(($failed + 1))
- fi
+ local file=$tdir/spoo-$i
+ $SETSTRIPE -p $pool $file
+ check_file_in_pool $file $pool "$tlist" || \
+ failed=$((failed + 1))
done
- [ "$failed" = 0 ] || error "$failed files not allocated in $POOL"
+ [ "$failed" = 0 ] && return 0
+
+ error_noexit "$failed files not allocated in $pool"
+ return 1
}
-run_test 200f "Create files in a pool ==================================="
-test_200g() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- TGT=$($LCTL get_param -n lov.$FSNAME-clilov-*.pools.$POOL | tr '\n' ' ')
- res=$($LFS df --pool $FSNAME.$POOL | awk '{print $1}' | grep "$FSNAME-OST" | tr '\n' ' ')
- [ "$res" = "$TGT" ] || error "Pools OSTs '$TGT' is not '$res' that lfs df reports"
+pool_lfs_df() {
+ echo "Checking 'lfs df' output"
+ local pool=$1
+
+ local t=$($LCTL get_param -n lov.$FSNAME-clilov-*.pools.$pool |
+ tr '\n' ' ')
+ local res=$($LFS df --pool $FSNAME.$pool |
+ awk '{print $1}' |
+ grep "$FSNAME-OST" |
+ tr '\n' ' ')
+ [ "$res" = "$t" ] && return 0
+
+ error_noexit "Pools OSTs '$t' is not '$res' that lfs df reports"
+ return 1
}
-run_test 200g "lfs df a pool ============================================"
-test_200h() { # b=24039
- mkdir -p $POOL_DIR || error "unable to create $POOL_DIR"
+pool_file_rel_path() {
+ echo "Creating files in a pool with relative pathname"
+ local pool=$1
+ local tdir=$2
- local file="/..$POOL_DIR/$tfile-1"
- $SETSTRIPE -p $POOL $file || error "unable to create $file"
+ mkdir -p $tdir ||
+ { error_noexit "unable to create $tdir"; return 1 ; }
+ local file="/..$tdir/$tfile-1"
+ $SETSTRIPE -p $pool $file ||
+ { error_noexit "unable to create $file" ; return 2 ; }
- cd $POOL_DIR
- $SETSTRIPE -p $POOL $tfile-2 || \
- error "unable to create $tfile-2 in $POOL_DIR"
+ cd $tdir
+ $SETSTRIPE -p $pool $tfile-2 || {
+ error_noexit "unable to create $tfile-2 in $tdir"
+ return 3
+ }
}
-run_test 200h "Create files in a pool with relative pathname ============"
-test_201a() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
- do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
- wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | grep $TGT" "" ||
- error "$TGT not removed from $FSNAME.$POOL"
+pool_remove_first_target() {
+ echo "Removing first target from a pool"
+ local pool=$1
+
+ local pname="lov.$FSNAME-*.pools.$pool"
+ local t=$($LCTL get_param -n $pname | head -1)
+ do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
+ wait_update $HOSTNAME "lctl get_param -n $pname | grep $t" "" || {
+ error_noexit "$t not removed from $FSNAME.$pool"
+ return 1
+ }
}
-run_test 201a "Remove a target from a pool ============================="
-test_201b() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u)
+pool_remove_all_targets() {
+ echo "Removing all targets from pool"
+ local pool=$1
+ local file=$2
+ local pname="lov.$FSNAME-*.pools.$pool"
+ for t in $($LCTL get_param -n $pname | sort -u)
do
- do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
- done
- wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL" "" ||
- error "Pool $FSNAME.$POOL cannot be drained"
- # striping on an empty/nonexistant pool should fall back to "pool of everything"
- touch ${POOL_DIR}/$tfile || error "failed to use fallback striping for empty pool"
+ do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
+ done
+ wait_update $HOSTNAME "lctl get_param -n $pname" "" || {
+ error_noexit "Pool $FSNAME.$pool cannot be drained"
+ return 1
+ }
+ # striping on an empty/nonexistant pool should fall back
+ # to "pool of everything"
+ touch $file || {
+ error_noexit "failed to use fallback striping for empty pool"
+ return 2
+ }
# setstripe on an empty pool should fail
- $SETSTRIPE -p $POOL ${POOL_FILE}/$tfile 2>/dev/null && \
- error "expected failure when creating file with empty pool"
+ $SETSTRIPE -p $pool $file 2>/dev/null && {
+ error_noexit "expected failure when creating file" \
+ "with empty pool"
+ return 3
+ }
return 0
}
-run_test 201b "Remove all targets from a pool =========================="
-test_201c() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- do_facet mgs $LCTL pool_destroy $FSNAME.$POOL
+pool_remove() {
+ echo "Destroying pool"
+ local pool=$1
+ local file=$2
+
+ do_facet mgs $LCTL pool_destroy $FSNAME.$pool
sleep 2
- # striping on an empty/nonexistant pool should fall back to "pool of everything"
- touch ${POOL_DIR}/$tfile || error "failed to use fallback striping for missing pool"
+ # striping on an empty/nonexistant pool should fall back
+ # to "pool of everything"
+ touch $file || {
+ error_noexit "failed to use fallback striping for missing pool"
+ return 1
+ }
# setstripe on an empty pool should fail
- $SETSTRIPE -p $POOL ${POOL_FILE}/$tfile 2>/dev/null && \
- error "expected failure when creating file with missing pool"
+ $SETSTRIPE -p $pool $file 2>/dev/null && {
+ error_noexit "expected failure when creating file" \
+ "with missing pool"
+ return 2
+ }
# get param should return err once pool is gone
- if wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL 2>/dev/null ||
- echo foo" "foo"; then
- remove_pool_from_list $FSNAME.$POOL
+ if wait_update $HOSTNAME "lctl get_param -n \
+ lov.$FSNAME-*.pools.$pool 2>/dev/null || echo foo" "foo"
+ then
+ remove_pool_from_list $FSNAME.$pool
return 0
fi
- error "Pool $FSNAME.$POOL is not destroyed"
+ error_noexit "Pool $FSNAME.$pool is not destroyed"
+ return 3
}
-run_test 201c "Remove a pool ============================================"
-cleanup_pools $FSNAME
+test_200() {
+ remote_mgs_nodsh && skip "remote MGS with nodsh" && return
+
+ local POOL=${POOL:-cea1}
+ local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
+ local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
+ # Pool OST targets
+ local first_ost=0
+ local last_ost=$(($OSTCOUNT - 1))
+ local ost_step=2
+ local ost_list=$(seq $first_ost $ost_step $last_ost)
+ local ost_range="$first_ost $last_ost $ost_step"
+ local test_path=$POOL_ROOT/$POOL_DIR_NAME
+ local file_dir=$POOL_ROOT/file_tst
+
+ local rc=0
+ while : ; do
+ # former test_200a test_200b
+ pool_add $POOL || { rc=$? ; break; }
+ pool_add_targets $POOL $ost_range || { rc=$? ; break; }
+ # former test_200c test_200d
+ mkdir -p $test_path
+ pool_set_dir $POOL $test_path || { rc=$? ; break; }
+ pool_check_dir $POOL $test_path || { rc=$? ; break; }
+ pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
+ || { rc=$? ; break; }
+ # former test_200e test_200f
+ local files=$((OSTCOUNT*3))
+ pool_alloc_files $POOL $test_path $files "$ost_list" \
+ || { rc=$? ; break; }
+ pool_create_files $POOL $file_dir $files "$ost_list" \
+ || { rc=$? ; break; }
+ # former test_200g test_200h
+ pool_lfs_df $POOL || { rc=$? ; break; }
+ pool_file_rel_path $POOL $test_path || { rc=$? ; break; }
+
+ # former test_201a test_201b test_201c
+ pool_remove_first_target $POOL || { rc=$? ; break; }
+
+ local f=$test_path/$tfile
+ pool_remove_all_targets $POOL $f || { rc=$? ; break; }
+ pool_remove $POOL $f || { rc=$? ; break; }
+ break
+ done
+
+ cleanup_pools
+ return $rc
+}
+run_test 200 "OST pools"
# usage: default_attr <count | size | offset>
default_attr() {
# clear old jobstats
do_facet $SINGLEMDS lctl set_param mdt.*.job_stats="clear"
- do_facet ost0 lctl set_param obdfilter.*.job_stats="clear"
+ do_facet ost1 lctl set_param obdfilter.*.job_stats="clear"
# use a new JobID for this test, or we might see an old one
[ "$JOBENV" = "FAKE_JOBID" ] && FAKE_JOBID=test_id.$testnum.$RANDOM
grep $JOBVAL || error "No job stats found on MDT $FACET"
fi
if [ "$target" = "ost" -o "$target" = "both" ]; then
- FACET=ost0
+ FACET=ost1
do_facet $FACET lctl get_param obdfilter.*.job_stats |
grep $JOBVAL || error "No job stats found on OST $FACET"
fi
}
test_205() { # Job stats
+ [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
+ skip "Server doesn't support jobstats" && return 0
+
local cmd
OLD_JOBENV=`$LCTL get_param -n jobid_var`
if [ $OLD_JOBENV != $JOBENV ]; then
}
run_test 205 "Verify job stats"
+# LU-1480, LU-1773 and LU-1657
+test_206() {
+ mkdir -p $DIR/$tdir
+ lfs setstripe -c -1 $DIR/$tdir
+#define OBD_FAIL_LOV_INIT 0x1403
+ $LCTL set_param fail_loc=0xa0001403
+ $LCTL set_param fail_val=1
+ touch $DIR/$tdir/$tfile || true
+}
+run_test 206 "fail lov_init_raid0() doesn't lbug"
+
test_212() {
size=`date +%s`
size=$((size % 8192 + 1))
}
run_test 227 "running truncated executable does not cause OOM"
+# LU-1512 try to reuse idle OI blocks
+test_228a() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
+
+ local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
+ local myDIR=$DIR/$tdir
+
+ mkdir -p $myDIR
+ #define OBD_FAIL_SEQ_EXHAUST 0x1002
+ $LCTL set_param fail_loc=0x80001002
+ createmany -o $myDIR/t- 10000
+ $LCTL set_param fail_loc=0
+ # The guard is current the largest FID holder
+ touch $myDIR/guard
+ local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
+ tr -d '[')
+ local IDX=$(($SEQ % 64))
+
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk1=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ # Remove old files, some OI blocks will become idle.
+ unlinkmany $myDIR/t- 10000
+ # Create new files, idle OI blocks should be reused.
+ createmany -o $myDIR/t- 2000
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk2=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
+}
+run_test 228a "try to reuse idle OI blocks"
+
+test_228b() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
+
+ local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
+ local myDIR=$DIR/$tdir
+
+ mkdir -p $myDIR
+ #define OBD_FAIL_SEQ_EXHAUST 0x1002
+ $LCTL set_param fail_loc=0x80001002
+ createmany -o $myDIR/t- 10000
+ $LCTL set_param fail_loc=0
+ # The guard is current the largest FID holder
+ touch $myDIR/guard
+ local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
+ tr -d '[')
+ local IDX=$(($SEQ % 64))
+
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk1=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ # Remove old files, some OI blocks will become idle.
+ unlinkmany $myDIR/t- 10000
+
+ # stop the MDT
+ stop $SINGLEMDS || error "Fail to stop MDT."
+ # remount the MDT
+ start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
+
+ df $MOUNT || error "Fail to df."
+ # Create new files, idle OI blocks should be reused.
+ createmany -o $myDIR/t- 2000
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk2=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
+}
+run_test 228b "idle OI blocks can be reused after MDT restart"
+
+#LU-1881
+test_228c() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
+
+ local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
+ local myDIR=$DIR/$tdir
+
+ mkdir -p $myDIR
+ #define OBD_FAIL_SEQ_EXHAUST 0x1002
+ $LCTL set_param fail_loc=0x80001002
+ # 20000 files can guarantee there are index nodes in the OI file
+ createmany -o $myDIR/t- 20000
+ $LCTL set_param fail_loc=0
+ # The guard is current the largest FID holder
+ touch $myDIR/guard
+ local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
+ tr -d '[')
+ local IDX=$(($SEQ % 64))
+
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk1=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ # Remove old files, some OI blocks will become idle.
+ unlinkmany $myDIR/t- 20000
+ rm -f $myDIR/guard
+ # The OI file should become empty now
+
+ # Create new files, idle OI blocks should be reused.
+ createmany -o $myDIR/t- 2000
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk2=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
+}
+run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
+
#
# tests that do cleanup/setup should be run at the end
#