common/rc: factor out _scratch_xfs_[get|set]_sb_field
[xfstests-dev.git] / common / fuzzy
index 75b23e10d3f94591da7ad5048b01f977ec70348e..9a0456fafaf4560d780b4c62029b68d90b84f7da 100644 (file)
@@ -39,7 +39,7 @@ _scratch_fuzz_modify() {
 
        echo "+++ create files"
        mkdir -p "${SCRATCH_MNT}/test.moo"
-       $XFS_IO_PROG -f -c 'pwrite -S 0x80 0 65536' "${SCRATCH_MNT}/test.moo/urk"
+       $XFS_IO_PROG -f -c 'pwrite -S 0x80 0 65536' "${SCRATCH_MNT}/test.moo/urk" > /dev/null
        sync
 
        echo "+++ remove files"
@@ -58,7 +58,7 @@ _scratch_fuzz_test() {
 # Do we have an online scrub program?
 _require_scrub() {
        case "${FSTYP}" in
-       "xfs"|"ext4")
+       "xfs")
                test -x "$XFS_SCRUB_PROG" || _notrun "xfs_scrub not found"
                ;;
        *)
@@ -70,7 +70,7 @@ _require_scrub() {
 # Scrub the scratch filesystem metadata (online)
 _scratch_scrub() {
        case "${FSTYP}" in
-       "xfs"|"ext4"|"ext3"|"ext2")
+       "xfs")
                $XFS_SCRUB_PROG -d -T -v "$@" $SCRATCH_MNT
                ;;
        *)
@@ -79,6 +79,14 @@ _scratch_scrub() {
        esac
 }
 
+# Filter out any keys with an array index >= 10, collapse any array range
+# ("[1-195]") to the first item, and ignore padding fields.
+__filter_xfs_db_keys() {
+       sed -e '/\([a-z]*\)\[\([0-9][0-9]\+\)\].*/d' \
+           -e 's/\([a-zA-Z0-9_]*\)\[\([0-9]*\)-[0-9]*\]/\1[\2]/g' \
+           -e '/pad/d'
+}
+
 # Filter the xfs_db print command's field debug information
 # into field name and type.
 __filter_xfs_db_print_fields() {
@@ -87,15 +95,13 @@ __filter_xfs_db_print_fields() {
                filter='^'
        fi
        grep ' = ' | while read key equals value; do
-               # Filter out any keys with an array index >= 10, and
-               # collapse any array range ("[1-195]") to the first item.
-               fuzzkey="$(echo "${key}" | sed -e '/\([a-z]*\)\[\([0-9][0-9]\+\)\].*/d' -e 's/\([a-zA-Z0-9_]*\)\[\([0-9]*\)-[0-9]*\]/\1[\2]/g')"
+               fuzzkey="$(echo "${key}" | __filter_xfs_db_keys)"
                if [ -z "${fuzzkey}" ]; then
                        continue
                elif [[ "${value}" == "["* ]]; then
                        echo "${value}" | sed -e 's/^.//g' -e 's/.$//g' -e 's/,/\n/g' | while read subfield; do
                                echo "${fuzzkey}.${subfield}"
-                       done
+                       done | __filter_xfs_db_keys
                else
                        echo "${fuzzkey}"
                fi
@@ -120,39 +126,6 @@ _scratch_xfs_list_metadata_fields() {
        _scratch_xfs_db "${cmds[@]}" -c print | __filter_xfs_db_print_fields "${filter}"
 }
 
-# Get a metadata field
-# The first arg is the field name
-# The rest of the arguments are xfs_db commands to find the metadata.
-_scratch_xfs_get_metadata_field() {
-       key="$1"
-       shift
-
-       grep_key="$(echo "${key}" | tr '[]()' '....')"
-       local cmds=()
-       for arg in "$@"; do
-               cmds+=("-c" "${arg}")
-       done
-       _scratch_xfs_db "${cmds[@]}" -c "print ${key}" | grep "^${grep_key}" | \
-               sed -e 's/^.* = //g'
-}
-
-# Set a metadata field
-# The first arg is the field name
-# The second arg is the new value
-# The rest of the arguments are xfs_db commands to find the metadata.
-_scratch_xfs_set_metadata_field() {
-       key="$1"
-       value="$2"
-       shift; shift
-
-       local cmds=()
-       for arg in "$@"; do
-               cmds+=("-c" "${arg}")
-       done
-       _scratch_xfs_db -x "${cmds[@]}" -c "write -d ${key} ${value}"
-       echo
-}
-
 # Fuzz a metadata field
 # The first arg is the field name
 # The second arg is the xfs_db fuzz verb
@@ -173,9 +146,14 @@ _scratch_xfs_fuzz_metadata_field() {
        for arg in "$@"; do
                cmds+=("-c" "${arg}")
        done
-       _scratch_xfs_db -x "${cmds[@]}" -c "fuzz ${fuzz_arg} ${key} ${value}"
-       echo
-       newval="$(_scratch_xfs_get_metadata_field "${key}" "$@" 2> /dev/null)"
+       while true; do
+               _scratch_xfs_db -x "${cmds[@]}" -c "fuzz ${fuzz_arg} ${key} ${value}"
+               echo
+               newval="$(_scratch_xfs_get_metadata_field "${key}" "$@" 2> /dev/null)"
+               if [ "${key}" != "random" ] || [ "${oldval}" != "${newval}" ]; then
+                       break;
+               fi
+       done
        if [ "${oldval}" = "${newval}" ]; then
                echo "Field ${key} already set to ${newval}, skipping test."
                return 1
@@ -274,7 +252,7 @@ __scratch_xfs_fuzz_field_test() {
                # which scrub doesn't know how to fix.
                echo "++ Online scrub"
                if [ "$1" != "sb 0" ]; then
-                       _scratch_scrub -e continue 2>&1
+                       _scratch_scrub -n -e continue 2>&1
                        res=$?
                        test $res -ne 0 && \
                                (>&2 echo "online re-scrub ($res) with ${field} = ${fuzzverb}.")
@@ -312,8 +290,8 @@ _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 '^Verbs:' | \
-               sed -e 's/[,.]//g' -e 's/Verbs: //g' -e 's/ /\n/g'
+       _scratch_xfs_db -x -c 'sb 0' -c 'fuzz' | grep '^Fuzz commands:' | \
+               sed -e 's/[,.]//g' -e 's/Fuzz commands: //g' -e 's/ /\n/g'
 }
 
 # Fuzz some of the fields of some piece of metadata