]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
fuzzy: test fuzzing realtime free space metadata
authorDarrick J. Wong <djwong@kernel.org>
Fri, 30 Dec 2022 22:19:45 +0000 (14:19 -0800)
committerZorro Lang <zlang@kernel.org>
Sat, 25 Feb 2023 13:27:47 +0000 (21:27 +0800)
Fuzz the contents of the realtime bitmap and summary files to see what
happens.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Zorro Lang <zlang@redhat.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
17 files changed:
common/fuzzy
tests/xfs/739 [new file with mode: 0755]
tests/xfs/739.out [new file with mode: 0644]
tests/xfs/740 [new file with mode: 0755]
tests/xfs/740.out [new file with mode: 0644]
tests/xfs/741 [new file with mode: 0755]
tests/xfs/741.out [new file with mode: 0644]
tests/xfs/742 [new file with mode: 0755]
tests/xfs/742.out [new file with mode: 0644]
tests/xfs/743 [new file with mode: 0755]
tests/xfs/743.out [new file with mode: 0644]
tests/xfs/744 [new file with mode: 0755]
tests/xfs/744.out [new file with mode: 0644]
tests/xfs/745 [new file with mode: 0755]
tests/xfs/745.out [new file with mode: 0644]
tests/xfs/746 [new file with mode: 0755]
tests/xfs/746.out [new file with mode: 0644]

index 224139d85baaa18417eceef052a1ee6a8813c3e0..470bec47da7c3ba4e8ff2db7779314724eab6a3a 100644 (file)
@@ -154,6 +154,12 @@ _scratch_xfs_dump_metadata() {
        _scratch_xfs_db "${cmds[@]}" -c print
 }
 
+# Decide from the output of the xfs_db "stack" command if the debugger's io
+# cursor is pointed at a block that is an unstructured data format (blob).
+__scratch_xfs_detect_blob_from_stack() {
+       grep -q -E 'inode.*, type (data|rtsummary|rtbitmap)'
+}
+
 # Navigate to some part of the filesystem and print the field info.
 # The first argument is an grep filter for the fields
 # The rest of the arguments are xfs_db commands to locate the metadata.
@@ -169,7 +175,17 @@ _scratch_xfs_list_metadata_fields() {
        for arg in "$@"; do
                cmds+=("-c" "${arg}")
        done
-       _scratch_xfs_db "${cmds[@]}" -c print | __filter_xfs_db_print_fields "${filter}"
+
+       # Does the path argument point towards something that is an
+       # unstructured blob?
+       if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+                       __scratch_xfs_detect_blob_from_stack; then
+               echo "<blob>"
+               return
+       fi
+
+       _scratch_xfs_db "${cmds[@]}" -c print | \
+               __filter_xfs_db_print_fields "${filter}"
 }
 
 # Fuzz a metadata field
@@ -207,6 +223,70 @@ _scratch_xfs_fuzz_metadata_field() {
        return 0
 }
 
+# List the fuzzing verbs available for unstructured blobs
+__scratch_xfs_list_blob_fuzz_verbs() {
+               cat << ENDL
+zeroes
+ones
+firstbit
+middlebit
+lastbit
+random
+ENDL
+}
+
+# Fuzz a metadata blob
+# The first arg is a blob fuzzing verb
+# The rest of the arguments are xfs_db commands to find the metadata.
+_scratch_xfs_fuzz_metadata_blob() {
+       local fuzzverb="$1"
+       shift
+       local trashcmd=(blocktrash -z)
+
+       local cmds=()
+       for arg in "$@"; do
+               cmds+=("-c" "${arg}")
+       done
+
+       local bytecount=$(_scratch_xfs_db "${cmds[@]}" -c "stack" | grep 'byte.*length' | awk '{print $5}')
+       local bitmax=$((bytecount * 8))
+
+       case "${fuzzverb}" in
+       "zeroes")
+               trashcmd+=(-0 -o 0 -x "${bitmax}" -y "${bitmax}");;
+       "ones")
+               trashcmd+=(-1 -o 0 -x "${bitmax}" -y "${bitmax}");;
+       "firstbit")
+               trashcmd+=(-2 -o 0 -x 1 -y 1);;
+       "middlebit")
+               trashcmd+=(-2 -o $((bitmax / 2)) -x 1 -y 1);;
+       "lastbit")
+               trashcmd+=(-2 -o "${bitmax}" -x 1 -y 1);;
+       "random")
+               trashcmd+=(-3 -o 0 -x "${bitmax}" -y "${bitmax}");;
+       *)
+               echo "Unknown blob fuzz verb \"${fuzzverb}\"."
+               return 1
+               ;;
+       esac
+
+       trashcmd="${trashcmd[@]}"
+       oldval="$(_scratch_xfs_get_metadata_field "" "$@")"
+       while true; do
+               _scratch_xfs_db -x "${cmds[@]}" -c "${trashcmd}"
+               echo
+               newval="$(_scratch_xfs_get_metadata_field "" "$@" 2> /dev/null)"
+               if [ "${fuzzverb}" != "random" ] || [ "${oldval}" != "${newval}" ]; then
+                       break;
+               fi
+       done
+       if [ "${oldval}" = "${newval}" ]; then
+               echo "Blob already set to new value, skipping test."
+               return 1
+       fi
+       return 0
+}
+
 # Try to forcibly unmount the scratch fs
 __scratch_xfs_fuzz_unmount()
 {
@@ -503,7 +583,11 @@ __scratch_xfs_fuzz_field_test() {
 
        # Set the new field value
        __fuzz_notify "+ Fuzz ${field} = ${fuzzverb}"
-       _scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+       if [ "$field" = "<blob>" ]; then
+               _scratch_xfs_fuzz_metadata_blob ${fuzzverb} "$@"
+       else
+               _scratch_xfs_fuzz_metadata_field "${field}" ${fuzzverb} "$@"
+       fi
        res=$?
        test $res -ne 0 && return
 
@@ -587,7 +671,22 @@ _scratch_xfs_list_fuzz_verbs() {
                echo "${SCRATCH_XFS_LIST_FUZZ_VERBS}" | tr '[ ,]' '[\n\n]'
                return;
        fi
-       _scratch_xfs_db -x -c 'sb 0' -c 'fuzz' | grep '^Fuzz commands:' | \
+
+       local cmds=()
+       for arg in "$@"; do
+               cmds+=("-c" "${arg}")
+       done
+       test "${#cmds[@]}" -eq 0 && cmds=('-c' 'sb 0')
+
+       # Does the path argument point towards something that is an
+       # unstructured blob?
+       if _scratch_xfs_db "${cmds[@]}" -c stack 2>/dev/null | \
+                       __scratch_xfs_detect_blob_from_stack; then
+               __scratch_xfs_list_blob_fuzz_verbs
+               return
+       fi
+
+       _scratch_xfs_db -x "${cmds[@]}" -c 'fuzz' | grep '^Fuzz commands:' | \
                sed -e 's/[,.]//g' -e 's/Fuzz commands: //g' -e 's/ /\n/g' | \
                grep -v '^random$'
 }
@@ -605,7 +704,7 @@ _scratch_xfs_fuzz_metadata() {
        shift; shift
 
        fields="$(_scratch_xfs_list_metadata_fields "${filter}" "$@")"
-       verbs="$(_scratch_xfs_list_fuzz_verbs)"
+       verbs="$(_scratch_xfs_list_fuzz_verbs "$@")"
        echo "Fields we propose to fuzz with the \"${repair}\" repair strategy: $@"
        echo $(echo "${fields}")
        echo "Verbs we propose to fuzz with:"
diff --git a/tests/xfs/739 b/tests/xfs/739
new file mode 100755 (executable)
index 0000000..fb7fe2e
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 739
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.bitmap')
+else
+       path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/739.out b/tests/xfs/739.out
new file mode 100644 (file)
index 0000000..7f0c604
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 739
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/740 b/tests/xfs/740
new file mode 100755 (executable)
index 0000000..a59fa37
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 740
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.summary')
+else
+       path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/740.out b/tests/xfs/740.out
new file mode 100644 (file)
index 0000000..bb86652
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 740
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/741 b/tests/xfs/741
new file mode 100755 (executable)
index 0000000..957bed7
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 741
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.bitmap')
+else
+       path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/741.out b/tests/xfs/741.out
new file mode 100644 (file)
index 0000000..db7a071
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 741
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/742 b/tests/xfs/742
new file mode 100755 (executable)
index 0000000..d911748
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 742
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.summary')
+else
+       path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/742.out b/tests/xfs/742.out
new file mode 100644 (file)
index 0000000..dd209a8
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 742
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/743 b/tests/xfs/743
new file mode 100755 (executable)
index 0000000..69e865a
--- /dev/null
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 743
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.bitmap')
+else
+       path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/743.out b/tests/xfs/743.out
new file mode 100644 (file)
index 0000000..d4ef1fd
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 743
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/744 b/tests/xfs/744
new file mode 100755 (executable)
index 0000000..ea490b5
--- /dev/null
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 744
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.summary')
+else
+       path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/744.out b/tests/xfs/744.out
new file mode 100644 (file)
index 0000000..99e0d48
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 744
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary
diff --git a/tests/xfs/745 b/tests/xfs/745
new file mode 100755 (executable)
index 0000000..7621d45
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 745
+#
+# Populate a XFS filesystem and fuzz every realtime bitmap field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtbitmap"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.bitmap')
+else
+       path=('sb' 'addr rbmino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtbitmap"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/745.out b/tests/xfs/745.out
new file mode 100644 (file)
index 0000000..0b8f207
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 745
+Format and populate
+Fuzz rtbitmap
+Done fuzzing rtbitmap
diff --git a/tests/xfs/746 b/tests/xfs/746
new file mode 100755 (executable)
index 0000000..4012331
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 746
+#
+# Populate a XFS filesystem and fuzz every realtime summary field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+echo "Fuzz rtsummary"
+is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
+if [ -n "$is_metadir" ]; then
+       path=('path -m /realtime/0.summary')
+else
+       path=('sb' 'addr rsumino')
+fi
+_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+echo "Done fuzzing rtsummary"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/746.out b/tests/xfs/746.out
new file mode 100644 (file)
index 0000000..375c7a0
--- /dev/null
@@ -0,0 +1,4 @@
+QA output created by 746
+Format and populate
+Fuzz rtsummary
+Done fuzzing rtsummary