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-10734 ..
-ALWAYS_EXCEPT=" 407 253 312 160g $ALWAYS_EXCEPT"
+# skipped tests: LU-8411 LU-9096 LU-9054 ..
+ALWAYS_EXCEPT=" 407 253 312 $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"
# 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)
+ 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]}"
- __changelog_clear $SINGLEMDS $cl_user1 +3
+ [ -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"
- local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user1)
+ 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
+ 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
- # 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"
+ 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_rec2 + 1
- local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
- awk '{ print $1; exit; }')
+ # 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 "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"
+ 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)"
}
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 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