From 8bdb40271c00b0718f9702d82455b238d2439ec7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 30 Dec 2022 14:19:06 -0800 Subject: [PATCH] xfs: race fsstress with online scrubbers for file metadata For each XFS_SCRUB_TYPE_* that looks at file metadata, create a test that runs that scrubber in the foreground and fsstress in the background. Signed-off-by: Darrick J. Wong Reviewed-by: Zorro Lang Signed-off-by: Zorro Lang --- common/fuzzy | 89 ++++++++++++++++++++++++++++++++++++++++++++--- tests/xfs/587 | 38 ++++++++++++++++++++ tests/xfs/587.out | 2 ++ tests/xfs/588 | 37 ++++++++++++++++++++ tests/xfs/588.out | 2 ++ tests/xfs/589 | 39 +++++++++++++++++++++ tests/xfs/589.out | 2 ++ tests/xfs/590 | 39 +++++++++++++++++++++ tests/xfs/590.out | 2 ++ tests/xfs/591 | 37 ++++++++++++++++++++ tests/xfs/591.out | 2 ++ tests/xfs/592 | 40 +++++++++++++++++++++ tests/xfs/592.out | 2 ++ tests/xfs/593 | 38 ++++++++++++++++++++ tests/xfs/593.out | 2 ++ tests/xfs/594 | 38 ++++++++++++++++++++ tests/xfs/594.out | 2 ++ tests/xfs/595 | 39 +++++++++++++++++++++ tests/xfs/595.out | 2 ++ 19 files changed, 447 insertions(+), 5 deletions(-) create mode 100755 tests/xfs/587 create mode 100644 tests/xfs/587.out create mode 100755 tests/xfs/588 create mode 100644 tests/xfs/588.out create mode 100755 tests/xfs/589 create mode 100644 tests/xfs/589.out create mode 100755 tests/xfs/590 create mode 100644 tests/xfs/590.out create mode 100755 tests/xfs/591 create mode 100644 tests/xfs/591.out create mode 100755 tests/xfs/592 create mode 100644 tests/xfs/592.out create mode 100755 tests/xfs/593 create mode 100644 tests/xfs/593.out create mode 100755 tests/xfs/594 create mode 100644 tests/xfs/594.out create mode 100755 tests/xfs/595 create mode 100644 tests/xfs/595.out diff --git a/common/fuzzy b/common/fuzzy index c4a5bc92..f7f660bc 100644 --- a/common/fuzzy +++ b/common/fuzzy @@ -330,12 +330,20 @@ __stress_freeze_filter_output() { # Filter scrub output so that we don't tarnish the golden output if the fs is # too busy to scrub. Note: Tests should _notrun if the scrub type is not -# supported. +# supported. Callers can provide extra strings to filter out as function +# arguments. __stress_scrub_filter_output() { + local extra_args=() + + for arg in "$@"; do + extra_args+=(-e "/${arg}/d") + done + _filter_scratch | \ sed -e '/Device or resource busy/d' \ -e '/Optimization possible/d' \ - -e '/No space left on device/d' + -e '/No space left on device/d' \ + "${extra_args[@]}" } # Decide if the scratch filesystem is still alive. @@ -401,13 +409,34 @@ __stress_one_scrub_loop() { fi done + local extra_filters=() + local target_cmd=(echo "$scrub_tgt") + case "$scrub_tgt" in + "%file%"|"%datafile%"|"%attrfile%") + extra_filters+=('No such file or directory' 'No such device or address') + target_cmd=(find "$SCRATCH_MNT" -print) + ;; + "%dir%") + extra_filters+=('No such file or directory' 'Not a directory') + target_cmd=(find "$SCRATCH_MNT" -type d -print) + ;; + "%regfile%"|"%cowfile%") + extra_filters+=('No such file or directory') + target_cmd=(find "$SCRATCH_MNT" -type f -print) + ;; + esac + while __stress_scrub_running "$scrub_startat" "$runningfile"; do sleep 1 done while __stress_scrub_running "$end" "$runningfile"; do - $XFS_IO_PROG -x "${xfs_io_args[@]}" "$scrub_tgt" 2>&1 | \ - __stress_scrub_filter_output + readarray -t fnames < <("${target_cmd[@]}" 2>/dev/null) + for fname in "${fnames[@]}"; do + $XFS_IO_PROG -x "${xfs_io_args[@]}" "$fname" 2>&1 | \ + __stress_scrub_filter_output "${extra_filters[@]}" + __stress_scrub_running "$end" "$runningfile" || break + done done } @@ -585,6 +614,22 @@ __stress_scrub_fsstress_loop() { "default") # No new arguments ;; + "symlink") + focus+=('-z') + + # Only create, read, and delete symbolic links + focus+=('-f' 'symlink=4') + focus+=('-f' 'readlink=10') + focus+=('-f' 'unlink=1') + ;; + "mknod") + focus+=('-z') + + # Only create and delete special files + focus+=('-f' 'mknod=4') + focus+=('-f' 'getdents=100') + focus+=('-f' 'unlink=1') + ;; *) echo "$stress_tgt: Unrecognized stress target, using defaults." ;; @@ -715,9 +760,31 @@ __stress_scrub_check_commands() { local scrub_tgt="$1" shift + local cooked_tgt="$scrub_tgt" + case "$scrub_tgt" in + "%file%"|"%dir%") + cooked_tgt="$SCRATCH_MNT" + ;; + "%regfile%"|"%datafile%") + cooked_tgt="$SCRATCH_MNT/testfile" + echo test > "$cooked_tgt" + ;; + "%attrfile%") + cooked_tgt="$SCRATCH_MNT/testfile" + $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 64k' "$cooked_tgt" &>/dev/null + attr -s attrname "$cooked_tgt" < "$cooked_tgt" &>/dev/null + ;; + "%cowfile%") + cooked_tgt="$SCRATCH_MNT/testfile" + $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 128k' "$cooked_tgt" &>/dev/null + _cp_reflink "$cooked_tgt" "$cooked_tgt.1" + $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 1' "$cooked_tgt.1" &>/dev/null + ;; + esac + for arg in "$@"; do local cooked_arg="$(echo "$arg" | sed -e "s/%agno%/0/g")" - testio=`$XFS_IO_PROG -x -c "$cooked_arg" $scrub_tgt 2>&1` + testio=`$XFS_IO_PROG -x -c "$cooked_arg" "$cooked_tgt" 2>&1` echo $testio | grep -q "Unknown type" && \ _notrun "xfs_io scrub subcommand support is missing" echo $testio | grep -q "Inappropriate ioctl" && \ @@ -749,6 +816,16 @@ __stress_scrub_check_commands() { # -S Pass this option to xfs_scrub. If zero -S options are specified, # xfs_scrub will not be run. To select repair mode, pass '-k' or '-v'. # -t Run online scrub against this file; $SCRATCH_MNT is the default. +# Special values are as follows: +# +# %file% all files +# %regfile% regular files +# %dir% direct +# %datafile% regular files with data blocks +# %attrfile% regular files with xattr blocks +# %cowfile% regular files with shared blocks +# +# File selection races with fsstress, so the selection is best-effort. # -w Delay the start of the scrub/repair loop by this number of seconds. # Defaults to no delay unless XFS_SCRUB_STRESS_DELAY is set. This value # will be clamped to ten seconds before the end time. @@ -758,6 +835,8 @@ __stress_scrub_check_commands() { # 'xattr': Grow extended attributes in a small tree. # 'default': Run fsstress with default arguments. # 'writeonly': Only perform fs updates, no reads. +# 'symlink': Only create symbolic links. +# 'mknod': Only create special files. # # The default is 'default' unless XFS_SCRUB_STRESS_TARGET is set. # -X Run this program to exercise the filesystem. Currently supported diff --git a/tests/xfs/587 b/tests/xfs/587 new file mode 100755 index 00000000..71e1ce69 --- /dev/null +++ b/tests/xfs/587 @@ -0,0 +1,38 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 587 +# +# Race fsstress and inode record scrub for a while to see if we crash or +# livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -s "scrub inode" -t "%file%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/587.out b/tests/xfs/587.out new file mode 100644 index 00000000..2d94c726 --- /dev/null +++ b/tests/xfs/587.out @@ -0,0 +1,2 @@ +QA output created by 587 +Silence is golden diff --git a/tests/xfs/588 b/tests/xfs/588 new file mode 100755 index 00000000..f56c50ac --- /dev/null +++ b/tests/xfs/588 @@ -0,0 +1,37 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 588 +# +# Race fsstress and data fork scrub for a while to see if we crash or livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -s "scrub bmapbtd" -t "%datafile%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/588.out b/tests/xfs/588.out new file mode 100644 index 00000000..5c2c4b24 --- /dev/null +++ b/tests/xfs/588.out @@ -0,0 +1,2 @@ +QA output created by 588 +Silence is golden diff --git a/tests/xfs/589 b/tests/xfs/589 new file mode 100755 index 00000000..d9cd81e0 --- /dev/null +++ b/tests/xfs/589 @@ -0,0 +1,39 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 589 +# +# Race fsstress and attr fork scrub for a while to see if we crash or livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs +. ./common/attr + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_attrs +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -x 'xattr' -s "scrub bmapbta" -t "%attrfile%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/589.out b/tests/xfs/589.out new file mode 100644 index 00000000..5ab6ab10 --- /dev/null +++ b/tests/xfs/589.out @@ -0,0 +1,2 @@ +QA output created by 589 +Silence is golden diff --git a/tests/xfs/590 b/tests/xfs/590 new file mode 100755 index 00000000..4e39109a --- /dev/null +++ b/tests/xfs/590 @@ -0,0 +1,39 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 590 +# +# Race fsstress and cow fork scrub for a while to see if we crash or livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs +. ./common/reflink + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_require_xfs_has_feature "$SCRATCH_MNT" reflink +_scratch_xfs_stress_scrub -s "scrub bmapbtc" -t "%cowfile%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/590.out b/tests/xfs/590.out new file mode 100644 index 00000000..c8f8be6f --- /dev/null +++ b/tests/xfs/590.out @@ -0,0 +1,2 @@ +QA output created by 590 +Silence is golden diff --git a/tests/xfs/591 b/tests/xfs/591 new file mode 100755 index 00000000..00d5114e --- /dev/null +++ b/tests/xfs/591 @@ -0,0 +1,37 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 591 +# +# Race fsstress and directory scrub for a while to see if we crash or livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -x 'dir' -s "scrub directory" -t "%dir%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/591.out b/tests/xfs/591.out new file mode 100644 index 00000000..e5707237 --- /dev/null +++ b/tests/xfs/591.out @@ -0,0 +1,2 @@ +QA output created by 591 +Silence is golden diff --git a/tests/xfs/592 b/tests/xfs/592 new file mode 100755 index 00000000..02ac456b --- /dev/null +++ b/tests/xfs/592 @@ -0,0 +1,40 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 592 +# +# Race fsstress and extended attributes scrub for a while to see if we crash or +# livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs +. ./common/attr + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_attrs +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -x 'xattr' -s "scrub xattr" -t "%attrfile%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/592.out b/tests/xfs/592.out new file mode 100644 index 00000000..f4ace929 --- /dev/null +++ b/tests/xfs/592.out @@ -0,0 +1,2 @@ +QA output created by 592 +Silence is golden diff --git a/tests/xfs/593 b/tests/xfs/593 new file mode 100755 index 00000000..cf2ac506 --- /dev/null +++ b/tests/xfs/593 @@ -0,0 +1,38 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 593 +# +# Race fsstress and parent pointers scrub for a while to see if we crash or +# livelock. +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +_scratch_xfs_stress_scrub -s "scrub parent" -t "%dir%" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/593.out b/tests/xfs/593.out new file mode 100644 index 00000000..bac4d7d9 --- /dev/null +++ b/tests/xfs/593.out @@ -0,0 +1,2 @@ +QA output created by 593 +Silence is golden diff --git a/tests/xfs/594 b/tests/xfs/594 new file mode 100755 index 00000000..323b191b --- /dev/null +++ b/tests/xfs/594 @@ -0,0 +1,38 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 594 +# +# Race fsstress and symlink scrub for a while to see if we crash or livelock. +# We can't open symlink files directly for scrubbing, so we use xfs_scrub(8). +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +XFS_SCRUB_PHASE=3 _scratch_xfs_stress_scrub -x 'symlink' -S '-n' + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/594.out b/tests/xfs/594.out new file mode 100644 index 00000000..2f67d684 --- /dev/null +++ b/tests/xfs/594.out @@ -0,0 +1,2 @@ +QA output created by 594 +Silence is golden diff --git a/tests/xfs/595 b/tests/xfs/595 new file mode 100755 index 00000000..fc2a89ed --- /dev/null +++ b/tests/xfs/595 @@ -0,0 +1,39 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. Inc. All Rights Reserved. +# +# FS QA Test No. 595 +# +# Race fsstress and special file scrub for a while to see if we crash or +# livelock. We can't open special files directly for scrubbing, so we use +# xfs_scrub(8). +# +. ./common/preamble +_begin_fstest scrub dangerous_fsstress_scrub + +_cleanup() { + _scratch_xfs_stress_scrub_cleanup &> /dev/null + cd / + rm -r -f $tmp.* +} +_register_cleanup "_cleanup" BUS + +# Import common functions. +. ./common/filter +. ./common/fuzzy +. ./common/inject +. ./common/xfs + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_xfs_stress_scrub + +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount +XFS_SCRUB_PHASE=3 _scratch_xfs_stress_scrub -x 'mknod' -S '-n' + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/595.out b/tests/xfs/595.out new file mode 100644 index 00000000..6040b9af --- /dev/null +++ b/tests/xfs/595.out @@ -0,0 +1,2 @@ +QA output created by 595 +Silence is golden -- 2.39.5