Re: [PATCH] btrfs/220: fix how we tests for mount options

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



On Wed, Nov 4, 2020 at 9:13 PM Josef Bacik <josef@xxxxxxxxxxxxxx> wrote:
>
> Filipe noticed that btrfs/220 started failing with some mount option
> changes I made recently, but upon closer inspection this test actually
> fails in a lot of different ways normally, specifically if you specify
> MOUNT_OPTIONS, or if you make an fs with the free space tree.
>
> Address all these issues by reworking how we test that the mount options
> are what we expect.  First get what the default mount options are for a
> plain mount of SCRATCH_DEV.  This is used as the baseline, so no matter
> how the mount options change in the future it will always work properly.
>
> Secondly instead of specifying a rigid order of the mount options we're
> testing, which breaks if we adjust the order in /proc/self/mounts,
> simply specify the options we're actually interested in checking.  Then
> in the test function combine the common options with the new options
> we're testing, and then combine that with our actual options and use
> some sort magic to see if there's any difference.  If there's no
> difference then we know we have everything set as expected, if not we
> fail.
>
> This patch addresses the initial issue that Filipe noticed, but also
> fixes the failures when you specified MOUNT_OPTIONS, or if you made the
> fs with the free space tree.
>
> Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>

Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx>

Looks good, I like the solution and makes it robust.
Thanks!

> ---
>  tests/btrfs/220 | 124 ++++++++++++++++++++++++++++++------------------
>  1 file changed, 77 insertions(+), 47 deletions(-)
>
> diff --git a/tests/btrfs/220 b/tests/btrfs/220
> index 8f4ba5c6..c84c7065 100755
> --- a/tests/btrfs/220
> +++ b/tests/btrfs/220
> @@ -39,13 +39,35 @@ test_mount_flags()
>  {
>         local opt
>         local opt_check
> +       local stripped
>         opt="$1"
>         opt_check="$2"
>
>         active_opt=$(cat /proc/self/mounts | grep $SCRATCH_MNT | \
>                                         $AWK_PROG '{ print $4 }')
> -       if [[ "$active_opt" != *$opt_check* ]]; then
> -               echo "Could not find '$opt_check' in '$active_opt', using '$opt'"
> +
> +       if [ "$opt_check" != "$DEFAULT_OPTS" ]; then
> +               # We only care about the common things between defaults and the
> +               # active set, so strip out the uniq lines between the two, and
> +               # then we'll add this to our $opt_check which should equal
> +               # $active_opt.  We also strip 'rw' as we may be checking 'ro',
> +               # so we need to adjust that accordingly
> +               stripped=$(echo "$DEFAULT_OPTS,$active_opt" | tr ',' '\n' | \
> +                               sort | grep -v 'rw' | uniq -d | tr '\n' ',' | \
> +                               sed 's/.$//')
> +               opt_check="$opt_check,$stripped"
> +       fi
> +
> +       # We diff by putting our wanted opts together with the current opts,
> +       # turning it into one option per line, sort'ing, and then printing out
> +       # any uniq lines left.  This will catch anything that is set that we're
> +       # not expecting, or anything that wasn't set that we wanted.
> +       #
> +       # We strip 'rw' because some tests flip ro, so just ignore rw.
> +       diff=$(echo "$opt_check,$active_opt" | tr ',' '\n' | \
> +               sort | grep -v 'rw' | uniq -u)
> +       if [ -n "$diff" ]; then
> +               echo "Unexepcted mount options, checking for '$opt_check' in '$active_opt' using '$opt'"
>         fi
>  }
>
> @@ -173,116 +195,124 @@ test_subvol()
>         # subvol and subvolid should point to the same subvolume
>         test_should_fail "-o subvol=vol1,subvolid=1234132"
>
> -       test_mount_opt "subvol=vol1,subvolid=256" "space_cache,subvolid=256,subvol=/vol1"
> -       test_roundtrip_mount "subvol=vol1" "space_cache,subvolid=256,subvol=/vol1" "subvolid=256" "space_cache,subvolid=256,subvol=/vol1"
> +       test_mount_opt "subvol=vol1,subvolid=256" "subvolid=256,subvol=/vol1"
> +       test_roundtrip_mount "subvol=vol1" "subvolid=256,subvol=/vol1" "subvolid=256" "subvolid=256,subvol=/vol1"
>  }
>
>  # These options are enable at kernel compile time, so no bother if they fail
>  test_optional_kernel_features()
>  {
>         # Test options that are enabled by kernel config, and so can fail safely
> -       test_optional_mount_opts "check_int" "space_cache,check_int,subvolid"
> -       test_optional_mount_opts "check_int_data" "space_cache,check_int_data,subvolid"
> -       test_optional_mount_opts "check_int_print_mask=123" "space_cache,check_int_print_mask=123,subvolid"
> +       test_optional_mount_opts "check_int" "check_int"
> +       test_optional_mount_opts "check_int_data" "check_int_data"
> +       test_optional_mount_opts "check_int_print_mask=123" "check_int_print_mask=123"
>
>         test_should_fail "fragment=invalid"
> -       test_optional_mount_opts "fragment=all" "space_cache,fragment=data,fragment=metadata,subvolid"
> -       test_optional_mount_opts "fragment=data" "space_cache,fragment=data,subvolid"
> -       test_optional_mount_opts "fragment=metadata" "space_cache,fragment=metadata,subvolid"
> +       test_optional_mount_opts "fragment=all" "fragment=data,fragment=metadata"
> +       test_optional_mount_opts "fragment=data" "fragment=data"
> +       test_optional_mount_opts "fragment=metadata" "fragment=metadata"
>  }
>
>  test_non_revertible_options()
>  {
> -       test_mount_opt "clear_cache" "relatime,space_cache,clear_cache,subvolid"
> -       test_mount_opt "degraded" "relatime,degraded,space_cache,subvolid"
> +       test_mount_opt "clear_cache" "clear_cache"
> +       test_mount_opt "degraded" "degraded"
>
> -       test_mount_opt "inode_cache" "space_cache,inode_cache,subvolid"
> +       test_mount_opt "inode_cache" "inode_cache"
>
>         # nologreplay should be used only with
>         test_should_fail "nologreplay"
> -       test_mount_opt "nologreplay,ro" "ro,relatime,rescue=nologreplay,space_cache"
> +       test_mount_opt "nologreplay,ro" "ro,rescue=nologreplay"
>
>         # norecovery should be used only with. This options is an alias to nologreplay
>         test_should_fail "norecovery"
> -       test_mount_opt "norecovery,ro" "ro,relatime,rescue=nologreplay,space_cache"
> -       test_mount_opt "rescan_uuid_tree" "relatime,space_cache,rescan_uuid_tree,subvolid"
> -       test_mount_opt "skip_balance" "relatime,space_cache,skip_balance,subvolid"
> -       test_mount_opt "user_subvol_rm_allowed" "space_cache,user_subvol_rm_allowed,subvolid"
> +       test_mount_opt "norecovery,ro" "ro,rescue=nologreplay"
> +       test_mount_opt "rescan_uuid_tree" "rescan_uuid_tree"
> +       test_mount_opt "skip_balance" "skip_balance"
> +       test_mount_opt "user_subvol_rm_allowed" "user_subvol_rm_allowed"
>
>         test_should_fail "rescue=invalid"
>
>         # nologreplay requires readonly
>         test_should_fail "rescue=nologreplay"
> -       test_mount_opt "rescue=nologreplay,ro" "relatime,rescue=nologreplay,space_cache"
> -
> -       test_mount_opt "rescue=usebackuproot,ro" "relatime,space_cache,subvolid"
> +       test_mount_opt "rescue=nologreplay,ro" "ro,rescue=nologreplay"
>  }
>
>  # All these options can be reverted (with their "no" counterpart), or can have
>  # their values set to default on remount
>  test_revertible_options()
>  {
> -       test_roundtrip_mount "acl" "relatime,space_cache,subvolid" "noacl" "relatime,noacl,space_cache,subvolid"
> -       test_roundtrip_mount "autodefrag" "relatime,space_cache,autodefrag" "noautodefrag" "relatime,space_cache,subvolid"
> -       test_roundtrip_mount "barrier" "relatime,space_cache,subvolid" "nobarrier" "relatime,nobarrier,space_cache,subvolid"
> +       test_roundtrip_mount "acl" "$DEFAULT_OPTS" "noacl" "noacl"
> +       test_roundtrip_mount "autodefrag" "autodefrag" "noautodefrag" "$DEFAULT_OPTS"
> +       test_roundtrip_mount "barrier" "$DEFAULT_OPTS" "nobarrier" "nobarrier"
>
>         test_should_fail "commit=-10"
>         # commit=0 sets the default, so btrfs hides this mount opt
> -       test_roundtrip_mount "commit=35" "relatime,space_cache,commit=35,subvolid" "commit=0" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "commit=35" "commit=35" "commit=0" "$DEFAULT_OPTS"
>
>         test_should_fail "compress=invalid"
>         test_should_fail "compress-force=invalid"
> -       test_roundtrip_mount "compress" "relatime,compress=zlib:3,space_cache,subvolid" "compress=lzo" "relatime,compress=lzo,space_cache,subvolid"
> -       test_roundtrip_mount "compress=zstd" "relatime,compress=zstd:3,space_cache,subvolid" "compress=no" "relatime,space_cache,subvolid"
> -       test_roundtrip_mount "compress-force=no" "relatime,space_cache,subvolid" "compress-force=zstd" "relatime,compress-force=zstd:3,space_cache,subvolid"
> +       test_roundtrip_mount "compress" "compress=zlib:3" "compress=lzo" "compress=lzo"
> +       test_roundtrip_mount "compress=zstd" "compress=zstd:3" "compress=no" "$DEFAULT_OPTS"
> +       test_roundtrip_mount "compress-force=no" "$DEFAULT_OPTS" "compress-force=zstd" "compress-force=zstd:3"
>         # zlib's max level is 9 and zstd's max level is 15
> -       test_roundtrip_mount "compress=zlib:20" "relatime,compress=zlib:9,space_cache,subvolid" "compress=zstd:16" "relatime,compress=zstd:15,space_cache,subvolid"
> -       test_roundtrip_mount "compress-force=lzo" "relatime,compress-force=lzo,space_cache,subvolid" "compress-force=zlib:4" "relatime,compress-force=zlib:4,space_cache,subvolid"
> +       test_roundtrip_mount "compress=zlib:20" "compress=zlib:9" "compress=zstd:16" "compress=zstd:15"
> +       test_roundtrip_mount "compress-force=lzo" "compress-force=lzo" "compress-force=zlib:4" "compress-force=zlib:4"
>
>         # on remount, if we only pass datacow after nodatacow was used it will remain with nodatasum
> -       test_roundtrip_mount "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid" "datacow,datasum" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datacow,datasum" "$DEFAULT_OPTS"
>         # nodatacow disabled compression
> -       test_roundtrip_mount "compress-force" "relatime,compress-force=zlib:3,space_cache,subvolid" "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid"
> +       test_roundtrip_mount "compress-force" "compress-force=zlib:3" "nodatacow" "nodatasum,nodatacow"
>
>         # nodatacow disabled both datacow and datasum, and datasum enabled datacow and datasum
> -       test_roundtrip_mount "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid" "datasum" "relatime,space_cache,subvolid"
> -       test_roundtrip_mount "nodatasum" "relatime,nodatasum,space_cache,subvolid" "datasum" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datasum" "$DEFAULT_OPTS"
> +       test_roundtrip_mount "nodatasum" "nodatasum" "datasum" "$DEFAULT_OPTS"
>
>         test_should_fail "discard=invalid"
> -       test_roundtrip_mount "discard" "relatime,discard,space_cache,subvolid" "discard=sync" "relatime,discard,space_cache,subvolid"
> -       test_roundtrip_mount "discard=async" "relatime,discard=async,space_cache,subvolid" "discard=sync" "relatime,discard,space_cache,subvolid"
> -       test_roundtrip_mount "discard=sync" "relatime,discard,space_cache,subvolid" "nodiscard" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "discard" "discard" "discard=sync" "discard"
> +       test_roundtrip_mount "discard=async" "discard=async" "discard=sync" "discard"
> +       test_roundtrip_mount "discard=sync" "discard" "nodiscard" "$DEFAULT_OPTS"
>
> -       test_roundtrip_mount "enospc_debug" "relatime,space_cache,enospc_debug,subvolid" "noenospc_debug" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "enospc_debug" "enospc_debug" "noenospc_debug" "$DEFAULT_OPTS"
>
>         test_should_fail "fatal_errors=pani"
>         # fatal_errors=bug is the default
> -       test_roundtrip_mount "fatal_errors=panic" "relatime,space_cache,fatal_errors=panic,subvolid" "fatal_errors=bug" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "fatal_errors=panic" "fatal_errors=panic" "fatal_errors=bug" "$DEFAULT_OPTS"
>
> -       test_roundtrip_mount "flushoncommit" "relatime,flushoncommit,space_cache,subvolid" "noflushoncommit" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "flushoncommit" "flushoncommit" "noflushoncommit" "$DEFAULT_OPTS"
>
>         # 2048 is the max_inline default value
> -       test_roundtrip_mount "max_inline=1024" "relatime,max_inline=1024,space_cache" "max_inline=2048" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "max_inline=1024" "max_inline=1024" "max_inline=2048" "$DEFAULT_OPTS"
>
> -       test_roundtrip_mount "metadata_ratio=0" "relatime,space_cache,subvolid" "metadata_ratio=10" "space_cache,metadata_ratio=10,subvolid"
> +       test_roundtrip_mount "metadata_ratio=0" "$DEFAULT_OPTS" "metadata_ratio=10" "metadata_ratio=10"
>
>         # ssd_spread implies ssd, while nossd_spread only disables ssd_spread
> -       test_roundtrip_mount "ssd_spread" "relatime,ssd_spread,space_cache" "nossd" "relatime,nossd,space_cache,subvolid"
> -       test_roundtrip_mount "ssd" "relatime,ssd,space_cache" "nossd" "relatime,nossd,space_cache,subvolid"
> -       test_mount_opt "ssd" "relatime,ssd,space_cache"
> +       test_roundtrip_mount "ssd_spread" "ssd_spread" "nossd" "nossd"
> +       test_roundtrip_mount "ssd" "ssd" "nossd" "nossd"
> +       test_mount_opt "ssd" "ssd"
>
>         test_should_fail "thread_pool=-10"
>         test_should_fail "thread_pool=0"
> -       test_roundtrip_mount "thread_pool=10" "relatime,thread_pool=10,space_cache" "thread_pool=50" "relatime,thread_pool=50,space_cache"
> +       test_roundtrip_mount "thread_pool=10" "thread_pool=10" "thread_pool=50" "thread_pool=50"
>
> -       test_roundtrip_mount "notreelog" "relatime,notreelog,space_cache" "treelog" "relatime,space_cache,subvolid"
> +       test_roundtrip_mount "notreelog" "notreelog" "treelog" "$DEFAULT_OPTS"
>  }
>
>  # real QA test starts here
>  _scratch_mkfs >/dev/null
>
> +# This test checks mount options, so having random MOUNT_OPTIONS set could
> +# affect the results of a few of these tests.
> +MOUNT_OPTIONS=
> +
>  # create a subvolume that will be used later
>  _scratch_mount
> +
> +# We need to save the current default options so we can validate our changes
> +# from one mount option to the next one.
> +DEFAULT_OPTS=$(cat /proc/self/mounts | grep $SCRATCH_MNT | \
> +               $AWK_PROG '{ print $4 }')
> +
>  $BTRFS_UTIL_PROG subvolume create "$SCRATCH_MNT/vol1" > /dev/null
>  touch "$SCRATCH_MNT/vol1/file.txt"
>  _scratch_unmount
> --
> 2.26.2
>


-- 
Filipe David Manana,

“Whether you think you can, or you think you can't — you're right.”




[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux