local stripe_size=$(do_facet $SINGLEMDS \
"$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
+ check_set_fallocate
+
# to allocate grant because it may run out due to test_15.
$LFS setstripe -c -1 $file1
dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
rm -f $file1
$LFS setstripe -c -1 $file1 # b=10919
- fsx -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
+ $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
error "fsx failed"
rm -f $file1
# O_DIRECT reads and writes must be aligned to the device block size.
- fsx -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 -Z -r 4096 \
+ $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 -Z -r 4096 \
-w 4096 $file1 $file2 || error "fsx with O_DIRECT failed."
}
run_test 16a "$FSXNUM iterations of dual-mount fsx"
local file2=$DIR2/$tfile
local stripe_size=($($LFS getstripe -S $DIR))
+ check_set_fallocate
+
# to allocate grant because it may run out due to test_15.
lfs setstripe -c -1 $file1
dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync ||
lfs setstripe -c -1 $file1 # b=10919
# -o is set to 8192 because writes < 1 page and between 1 and 2 pages
# create a mix of tiny writes & normal writes
- fsx -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -o 8192 -S 0 \
+ $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -o 8192 -S 0 \
$file1 $file2 || error "fsx with tiny write failed."
}
run_test 16b "$FSXNUM iterations of dual-mount fsx at small size"
[ "$ost1_FSTYPE" != ldiskfs ] && skip "dio on ldiskfs only"
+ check_set_fallocate
+
# to allocate grant because it may run out due to test_15.
$LFS setstripe -c -1 $file1
dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
set_osd_param $list '' writethrough_cache_enable 0
$LFS setstripe -c -1 $file1 # b=10919
- fsx -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
+ $FSX -c 50 -p $FSXP -N $FSXNUM -l $((SIZE * 256)) -S 0 $file1 $file2 ||
error "fsx failed"
rm -f $file1
local file1=$DIR1/$tfile
local file2=$DIR2/$tfile
local file3=$DIR1/file
+ local tmpfile=$(mktemp)
local stripe_size=$(do_facet $SINGLEMDS \
"$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
# to allocate grant because it may run out due to test_15.
$LFS setstripe -c -1 $file1
+ stack_trap "rm -f $file1 $file2 $file3 $tmpfile"
dd if=/dev/zero of=$file1 bs=$stripe_size count=$OSTCOUNT oflag=sync
dd if=/dev/zero of=$file2 bs=$stripe_size count=$OSTCOUNT oflag=sync
rm -f $file1
- local tmpfile=`mktemp`
$LFS setstripe -c -1 $file1 # b=10919
$LCTL set_param ldlm.namespaces.*.lru_size=clear
# buffer read from another client
dd if=$file2 of=$file3 bs=1M count=100
diff $file3 $tmpfile || error "file different(3)"
-
- rm -f $file1 $file2 $file3 $tmpfile
-
}
run_test 16d "Verify DIO and buffer IO with two clients"
test_16e() { # LU-13227
+ # issue: LU-14314
+
+ (( "$MDS1_VERSION" >= $(version_code 2.13.53) )) ||
+ skip "Need MDS version at least 2.13.53"
+
local file1=$DIR1/$tfile
local file2=$DIR2/$tfile
run_test 19 "test concurrent uncached read races ==============="
test_20() {
- test_mkdir $DIR1/d20
+ test_mkdir $DIR1/$tdir
cancel_lru_locks
- CNT=$((`lctl get_param -n llite.*.dump_page_cache | wc -l`))
- $MULTIOP $DIR1/f20 Ow8190c
- $MULTIOP $DIR2/f20 Oz8194w8190c
- $MULTIOP $DIR1/f20 Oz0r8190c
+ CNT=$($LCTL get_param -n llite.*.dump_page_cache | wc -l)
+ $MULTIOP $DIR1/$tdir/$tfile Ow8190c
+ $MULTIOP $DIR2/$tdir/$tfile Oz8194w8190c
+ $MULTIOP $DIR1/$tdir/$tfile Oz0r8190c
cancel_lru_locks
- CNTD=$((`lctl get_param -n llite.*.dump_page_cache | wc -l` - $CNT))
- [ $CNTD -gt 0 ] && \
- error $CNTD" page left in cache after lock cancel" || true
+ CNT2=$($LCTL get_param -n llite.*.dump_page_cache | wc -l)
+ [[ $CNT2 == $CNT ]] ||
+ error $((CNT2 - CNT))" page left in cache after lock cancel"
}
run_test 20 "test extra readahead page left in cache ===="
lctl clear
dd if=/dev/zero of=$DIR2/$tfile bs=$((4096+4))k conv=notrunc count=4 seek=3 &
DD2_PID=$!
- usleep 50
+ sleep 0.5
log "dd 1 started"
dd if=/dev/zero of=$DIR1/$tfile bs=$((16384-1024))k conv=notrunc count=1 seek=4 &
log "checking cached lockless truncate"
$TRUNCATE $DIR1/$tfile 8000000
- $CHECKSTAT -s 8000000 $DIR2/$tfile || error "wrong file size"
+ $CHECKSTAT -s 8000000 $DIR2/$tfile ||
+ error "cached truncate - wrong file size"
[ $(calc_stats $OSC.*.${OSC}_stats lockless_truncate) -ne 0 ] ||
error "cached truncate isn't lockless"
log "checking not cached lockless truncate"
$TRUNCATE $DIR2/$tfile 5000000
- $CHECKSTAT -s 5000000 $DIR1/$tfile || error "wrong file size"
+ $CHECKSTAT -s 5000000 $DIR1/$tfile ||
+ error "not cached truncate - wrong file size"
[ $(calc_stats $OSC.*.${OSC}_stats lockless_truncate) -ne 0 ] ||
error "not cached truncate isn't lockless"
enable_lockless_truncate 0
clear_stats $OSC.*.${OSC}_stats
$TRUNCATE $DIR2/$tfile 3000000
- $CHECKSTAT -s 3000000 $DIR1/$tfile || error "wrong file size"
+ $CHECKSTAT -s 3000000 $DIR1/$tfile ||
+ error "lockless truncate disabled - wrong file size"
[ $(calc_stats $OSC.*.${OSC}_stats lockless_truncate) -eq 0 ] ||
error "lockless truncate disabling failed"
rm -f $DIR1/$tfile
}
run_test 41h "pdirops: create vs readdir =============="
+sub_test_41i() {
+ local PID1 PID2
+ local fail_loc="$1"
+ local ret=0
+
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
+
+ $MULTIOP $DIR1/$tfile oO_CREAT:O_EXCL:c 2>/dev/null &
+ PID1=$!
+ sleep 0.2
+ $MULTIOP $DIR2/$tfile oO_CREAT:O_EXCL:c 2>/dev/null &
+ PID2=$!
+
+ if ! wait $PID1 && ! wait $PID2; then
+ echo "Both creates failed (1 should fail, 1 should succeed)"
+ ret=1
+ elif wait $PID1 && wait $PID2; then
+ echo "Both creates succeeded (1 should fail, 1 should succeed)"
+ ret=2
+ fi
+
+ #Clean
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
+ rm -f $DIR/$tfile
+
+ return $ret
+}
+
+test_41i() {
+ [[ $MDS1_VERSION -le $(version_code 2.13.56) ]] ||
+ skip "Need MDS version newer than 2.13.56"
+ local msg fail_loc
+
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN 0x169
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2 0x16a
+ for fail_loc in "0x80000169" "0x8000016a"; do
+ echo "Begin 100 tests with fail_loc=$fail_loc"
+ printf "Progress: "
+ for i in {1..100}; do
+ printf "*"
+ msg=$(sub_test_41i "$fail_loc") ||
+ { echo; error "iter=$i : $msg"; }
+ done
+ echo
+ done
+}
+run_test 41i "reint_open: create vs create"
+
+
# test 42: unlink and blocking operations
test_42a() {
pdo_lru_clear
}
run_test 43j "racy mkdir return EEXIST =============="
+sub_test_43k() {
+ local PID1 PID2
+ local fail_loc="$1"
+ local ret=0
+
+ # We test in a separate directory to be able to unblock server thread in
+ # cfs_race() if LCK_PW is taken on the parent by mdt_reint_unlink.
+ test_mkdir $DIR2/$tdir
+ touch $DIR2/$tdir/$tfile
+
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
+ echo content > $DIR1/$tdir/$tfile & PID1=$!
+ pdo_sched
+ multiop $DIR2/$tdir/$tfile u & PID2=$!
+
+ wait $PID1 ||
+ { ret=$?; \
+ echo -n "overwriting $tfile should succeed (err=$ret); "; }
+ wait $PID2 ||
+ { ret=$?; \
+ echo -n "unlinking $tfile should succeed (err=$ret);"; }
+
+ #Clean
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
+ rm -rf $DIR/$tdir
+
+ return $ret
+}
+
+test_43k() {
+ [[ $MDS1_VERSION -le $(version_code 2.13.56) ]] ||
+ skip "Need MDS version newer than 2.13.56"
+ local msg fail_loc
+
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN 0x169
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2 0x16a
+ for fail_loc in "0x80000169" "0x8000016a"; do
+ echo "Begin 100 tests with fail_loc=$fail_loc"
+ printf "Progress: "
+ for i in {1..100}; do
+ printf "*"
+ msg=$(sub_test_43k "$fail_loc") ||
+ { echo; error "iter=$i : $msg"; }
+ done
+ echo
+ done
+
+ #Clean
+ reset_fail_loc
+
+ return 0
+}
+run_test 43k "unlink vs create"
+
# test 44: rename tgt and blocking operations
test_44a() {
pdo_lru_clear
}
run_test 45i "pdirops: rename src vs remote mkdir"
+sub_test_45j() {
+ local PID1 PID2
+ local fail_loc="$1"
+ local ret=0
+
+ # We test in a sparate directory to be able to unblock server thread in
+ # cfs_race if LCK_PW is taken on the parent by mdt_reint_rename.
+ test_mkdir $DIR2/$tdir
+ echo file1 > $DIR2/$tdir/$tfile
+ echo file2 > $DIR2/$tdir/$tfile-2
+
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=${fail_loc} || true" &>/dev/null
+
+ cat $DIR1/$tdir/$tfile >/dev/null &
+ PID1=$!
+ pdo_sched
+ mrename $DIR2/$tdir/$tfile-2 $DIR2/$tdir/$tfile > /dev/null &
+ PID2=$!
+
+ wait $PID1 ||
+ { ret=$?; echo -n "cat $tfile should succeed (err=$ret); "; }
+ wait $PID2 ||
+ { ret=$?; \
+ echo -n "mrename $tfile-2 to $tfile failed (err=$ret);"; }
+
+ #Clean
+ do_nodes $(comma_list $(mdts_nodes)) \
+ "lctl set_param -n fail_loc=0x0 || true" &>/dev/null
+ rm -rf $DIR/$tdir
+
+ return $ret
+}
+
+test_45j() {
+ [[ $MDS1_VERSION -le $(version_code 2.13.56) ]] ||
+ skip "Need MDS version newer than 2.13.56"
+ local msg fail_loc
+
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN 0x169
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_REINT_OPEN2 0x16a
+ for fail_loc in "0x80000169" "0x8000016a"; do
+ echo "Begin 100 tests with fail_loc=$fail_loc"
+ printf "Progress: "
+ for i in {1..100}; do
+ printf "*"
+ msg=$(sub_test_45j "$fail_loc") ||
+ { echo; error "iter=$i : $msg"; }
+ done
+ echo
+ done
+}
+run_test 45j "read vs rename =============="
+
# test 46: link and blocking operations
test_46a() {
pdo_lru_clear
# delay glimpse so that layout has changed when glimpse finish
#define OBD_FAIL_GLIMPSE_DELAY 0x1404
- $LCTL set_param fail_loc=0x1404
+ $LCTL set_param fail_loc=0x1404 fail_val=4
stat -c %s $DIR2/$tfile |tee $tmpfile &
local pid=$!
- sleep 1
+ sleep 0.2
# extend layout of testing file
dd if=/dev/zero of=$DIR1/$tfile bs=1M count=1 seek=2 conv=notrunc ||
}
run_test 51d "layout lock: losing layout lock should clean up memory map region"
+test_51e() {
+ local pid
+
+ $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
+ pid=$!
+ sleep 1
+
+ $LFS getstripe $DIR2/$tfile
+ kill -USR1 $pid
+ wait $pid || error "multiop failed"
+
+ $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
+ pid=$!
+ sleep 1
+
+ $LFS getstripe $DIR2/$tfile
+ kill -USR1 $pid
+ wait $pid || error "multiop failed"
+}
+run_test 51e "lfs getstripe does not break leases, part 2"
+
test_54_part1()
{
echo "==> rename vs getattr vs setxattr should not deadlock"
}
run_test 81b "rename under striped directory doesn't deadlock"
+test_81c() {
+ [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
+ [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
+ skip "Need MDS version at least 2.13.52"
+
+ # source is local, source parent is remote
+ $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
+ $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
+ $LFS mkdir -i 3 $DIR1/${tdir}_src/sub || error "mkdir sub"
+ $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
+ stat $DIR2/${tdir}_src/sub || error "stat sub failed"
+ mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
+ [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
+ rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
+
+ # source is remote, source parent is local
+ $LFS mkdir -i 3 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
+ $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
+ $LFS mkdir -i 0 $DIR1/${tdir}_src/sub || error "mkdir sub"
+ $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
+ stat $DIR2/${tdir}_src/sub || error "stat sub failed"
+ mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
+ [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
+ rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
+
+ # source and source parent are remote
+ $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
+ $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
+ mkdir $DIR1/${tdir}_src/sub || error "mkdir sub"
+ $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
+ stat $DIR2/${tdir}_src/sub || error "stat sub failed"
+ mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
+ [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone"
+ rm -rf $DIR1/${tdir}_src $DIR1/${tdir}_tgt
+
+ # source and source parent are remote, and source is remote object
+ $LFS mkdir -i 0 $DIR1/${tdir}_src || error "mkdir ${tdir}_src"
+ $LFS mkdir -i 1 $DIR1/${tdir}_tgt || error "mkdir ${tdir}_tgt"
+ $LFS mkdir -i 2 $DIR1/${tdir}_src/sub || error "mkdir sub"
+ $LFS mkdir -i 3 $DIR1/${tdir}_tgt/sub || error "mkdir sub"
+ stat $DIR2/${tdir}_src/sub || error "stat sub failed"
+ mv $DIR1/${tdir}_src/sub $DIR1/${tdir}_tgt/ || error "mv failed"
+ [ -f $DIR2/${tdir}_src/sub ] && error "sub should be gone" || true
+}
+run_test 81c "rename revoke LOOKUP lock for remote object"
+
test_82() {
[[ "$MDS1_VERSION" -gt $(version_code 2.6.91) ]] ||
skip "Need MDS version at least 2.6.92"
local mdt_xtimes=($(get_mdt_xtimes $mdtdev))
echo "STAT a|m|ctime ${xtimes[*]}"
- echo "MDT a|m|ctime ${xtimes[*]}"
+ echo "MDT a|m|ctime ${mdt_xtimes[*]}"
[[ ${xtimes[0]} == ${mdt_xtimes[0]} ]] ||
error "$DIR/$tfile atime (${xtimes[0]}:${mdt_xtimes[0]}) diff"
[[ ${xtimes[1]} == ${mdt_xtimes[1]} ]] ||
}
run_test 106c "Verify statx attributes mask"
+test_107a() { # LU-1031
+ dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
+ local gid1=14091995
+ local gid2=16022000
+
+ $LFS getstripe $DIR1/$tfile
+
+ multiop_bg_pause $DIR1/$tfile OG${gid1}_g${gid1}c || return 1
+ local MULTIPID1=$!
+ multiop_bg_pause $DIR2/$tfile O_G${gid2}r10g${gid2}c || return 2
+ local MULTIPID2=$!
+ kill -USR1 $MULTIPID2
+ sleep 2
+ if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
+ error "First grouplock does not block second one"
+ else
+ echo "First grouplock blocks second one"
+ fi
+ kill -USR1 $MULTIPID1
+ wait $MULTIPID1
+ wait $MULTIPID2
+}
+run_test 107a "Basic grouplock conflict"
+
+test_107b() {
+ dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
+ local gid1=14091995
+ local gid2=16022000
+
+ $LFS getstripe $DIR1/$tfile
+
+ multiop_bg_pause $DIR1/$tfile OG${gid1}_g${gid1}c || return 1
+ local MULTIPID1=$!
+ multiop $DIR2/$tfile Or10c &
+ local MULTIPID2=$!
+ sleep 2
+
+ if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
+ error "Grouplock does not block IO"
+ else
+ echo "Grouplock blocks IO"
+ fi
+
+ multiop $DIR2/$tfile OG${gid2}_g${gid2}c &
+ local MULTIPID3=$!
+ sleep 2
+ if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
+ error "First grouplock does not block second one"
+ else
+ echo "First grouplock blocks second one"
+ fi
+
+ kill -USR1 $MULTIPID1
+ sleep 2
+
+ if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
+ error "Second grouplock thread disappeared"
+ fi
+
+ if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
+ error "Second grouplock does not block IO"
+ else
+ echo "Second grouplock blocks IO"
+ fi
+
+ kill -USR1 $MULTIPID3
+ wait $MULTIPID1
+ wait $MULTIPID2
+ wait $MULTIPID3
+}
+run_test 107b "Grouplock is added to the head of waiting list"
+
+test_108a() {
+ local offset
+
+ $LFS setstripe -E 1M -c 1 -E -1 $DIR1/$tfile ||
+ error "Create $DIR1/$tfile failed"
+
+ dd if=/dev/zero of=$DIR1/$tfile bs=10000 count=1 ||
+ error "dd $DIR1/$tfile failed"
+ offset=$(lseek_test -d 5000 $DIR2/$tfile)
+ [[ $offset == 5000 ]] || error "offset $offset != 5000"
+
+ $TRUNCATE $DIR1/$tfile 2000
+ offset=$(lseek_test -l 1000 $DIR2/$tfile)
+ [[ $offset == 2000 ]] || error "offset $offset != 2000"
+
+ #define OBD_FAIL_OSC_DELAY_IO 0x414
+ $LCTL set_param fail_val=4 fail_loc=0x80000414
+ dd if=/dev/zero of=$DIR1/$tfile count=1 bs=8M conv=notrunc oflag=dsync &
+ local pid=$!
+ sleep 2
+
+ offset=$(lseek_test -l 8000 $DIR2/$tfile)
+ wait $pid
+ [[ $offset == 8388608 ]] || error "offset $offset != 8388608"
+}
+run_test 108a "lseek: parallel updates"
+
+# LU-14110
+test_109() {
+ local i
+ local pid1 pid2
+
+ ! local_mode ||
+ skip "Clients need to be on different nodes than the servers"
+
+ umount_client $MOUNT
+ umount_client $MOUNT2
+
+ echo "Starting race between client mount instances (50 iterations):"
+ for i in {1..50}; do
+ log "Iteration $i"
+
+#define OBD_FAIL_ONCE|OBD_FAIL_LLITE_RACE_MOUNT 0x80001417
+ $LCTL set_param -n fail_loc=0x80001417
+
+ mount_client $MOUNT & pid1=$!
+ mount_client $MOUNT2 & pid2=$!
+ wait $pid1 || error "Mount $MOUNT fails with $?"
+ wait $pid2 || error "Mount $MOUNT2 fails with $?"
+
+ umount_client $MOUNT & pid1=$!
+ umount_client $MOUNT2 & pid2=$!
+ wait $pid1 || error "Umount $MOUNT fails with $?"
+ wait $pid2 || error "Umount $MOUNT2 fails with $?"
+
+ $LUSTRE_RMMOD || error "Fail to remove lustre modules"
+ load_modules
+ echo
+ done
+
+ mount_client $MOUNT
+ mount_client $MOUNT2
+}
+
+run_test 109 "Race with several mount instances on 1 node"
+
log "cleanup: ======================================================"
# kill and wait in each test only guarentee script finish, but command in script