Message ID | 20230830221943.3375955-1-gpiccoli@igalia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: Add test for the single-dev feature | expand |
Thanks for the test cases. These test cases might need to be updated as per the final changes in the kernel patches. > > [0] https://lore.kernel.org/linux-btrfs/20230803154453.1488248-1-gpiccoli@igalia.com/ > > > tests/btrfs/300 | 107 ++++++++++++++++++++++++++++++++++++++++++++ > tests/btrfs/300.out | 5 +++ > 2 files changed, 112 insertions(+) > create mode 100755 tests/btrfs/300 > create mode 100644 tests/btrfs/300.out > > diff --git a/tests/btrfs/300 b/tests/btrfs/300 > new file mode 100755 > index 000000000000..120e790906ea > --- /dev/null > +++ b/tests/btrfs/300 > @@ -0,0 +1,107 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2023 Guilherme G. Piccoli (Igalia S.L.). All Rights Reserved. > +# > +# FS QA Test 300 > +# > +# Test for the btrfs single-dev feature - both mkfs and btrfstune are > +# validated, as well as explicitly unsupported commands, like device > +# removal / replacement. > +# > +. ./common/preamble > +_begin_fstest auto mkfs quick > +. ./common/filter > +_supported_fs btrfs > + > +_require_btrfs_mkfs_feature single-dev > +_require_btrfs_fs_feature single_dev > + > +_require_scratch_dev_pool 2 > +_scratch_dev_pool_get 2 We can use _scratch_dev_pool_get 1 _spare_dev_get So scratch devices are set to SCRATCH_DEV and SPARE_DEV. > + > +_require_command "$BTRFS_TUNE_PROG" btrfstune > +_require_command "$WIPEFS_PROG" wipefs > + > +# Used random hash to avoid name collision. > +DIR_a="563b01de1f_a" > +DIR_b="563b01de1f_b" > + > +# Override the default cleanup function. > +_cleanup() > +{ > + cd / > + rm -r -f $tmp.* > + rm -rf $SCRATCH_MNT/$DIR_a > + rm -rf $SCRATCH_MNT/$DIR_b > +} > + > +# Helper to mount a btrfs fs > +# Arg 1: device > +# Arg 2: mount point > +mount_btrfs() > +{ > + $MOUNT_PROG -t btrfs $1 $2 > + [ $? -ne 0 ] && _fail "mounting $1 on $2 failed" > +} > + > +mkdir $SCRATCH_MNT/$DIR_a > +mkdir $SCRATCH_MNT/$DIR_b we can use something like: test_dir="${TEST_DIR}/${seq}" scratch_mnt_copy=$test_dir/mnt_copy > + > +DEV1=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $1 }') > +DEV2=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $2 }') A general rule of thumb is to have one test case per file. > +# Part 1 > +# First test involves a mkfs with single-dev feature enabled. > +# If it succeeds and mounting that FS *twice* also succeeds, > +# we're good and continue. > +$WIPEFS_PROG -a $DEV1 >> $seqres.full 2>&1 > +$WIPEFS_PROG -a $DEV2 >> $seqres.full 2>&1 > + > +$MKFS_BTRFS_PROG -O single-dev $DEV1 >>$seqres.full 2>&1 _scratch_mkfs "-b 300m -O single-dev" The '-b 300m' option prevents the below 'dd' operation from taking too long to complete on larger devices. > +dd if=$DEV1 of=$DEV2 bs=64M conv=fsync >> $seqres.full 2>&1 > + dd if=$SCRATCH_DEV of=SPARE_DEV bs=300m count=1 conv=fsync >> $seqres.full 2>&1 > +mount_btrfs $DEV1 $SCRATCH_MNT/$DIR_a > +mount_btrfs $DEV2 $SCRATCH_MNT/$DIR_b _scratch_mount _mount $SPARE_DEV $scratch_mnt_copy _spare_dev_put _scratch_dev_pool_put status=0 exit > + > +$UMOUNT_PROG $SCRATCH_MNT/$DIR_b > +$UMOUNT_PROG $SCRATCH_MNT/$DIR_a > + > + > +# Part 2 > +# Second test is similar to the first with the difference we > +# run mkfs with no single-dev mention, and make use of btrfstune > +# to set such feature. > +$WIPEFS_PROG -a $DEV1 >> $seqres.full 2>&1 > +$WIPEFS_PROG -a $DEV2 >> $seqres.full 2>&1 > + > +$MKFS_BTRFS_PROG $DEV1 >>$seqres.full 2>&1 > +$BTRFS_TUNE_PROG --convert-to-single-device $DEV1 > +dd if=$DEV1 of=$DEV2 bs=64M conv=fsync >> $seqres.full 2>&1 > + > +mount_btrfs $DEV1 $SCRATCH_MNT/$DIR_a > +mount_btrfs $DEV2 $SCRATCH_MNT/$DIR_b > + > +$UMOUNT_PROG $SCRATCH_MNT/$DIR_b > +$UMOUNT_PROG $SCRATCH_MNT/$DIR_a > + > + > +# Part 3 > +# Final part attempts to run some single-dev unsupported commands, > +# like device replace/remove - it they fail, test succeeds! > +mount_btrfs $DEV1 $SCRATCH_MNT > + > +$BTRFS_UTIL_PROG device replace start $DEV1 $DEV1 $SCRATCH_MNT 2>&1 \ > + | _filter_scratch > + > +$BTRFS_UTIL_PROG device remove $DEV1 $SCRATCH_MNT 2>&1 \ > + | sed -e "s,\B$DEV1,DEV1,g" > + > +$UMOUNT_PROG $SCRATCH_MNT > +_scratch_dev_pool_put 2 > + > +# success, all done > +status=0 > +echo "Finished" > + > +exit > diff --git a/tests/btrfs/300.out b/tests/btrfs/300.out > new file mode 100644 > index 000000000000..5f13cfb228fb > --- /dev/null > +++ b/tests/btrfs/300.out > @@ -0,0 +1,5 @@ > +QA output created by 300 > +ERROR: ioctl(DEV_REPLACE_STATUS) failed on "SCRATCH_MNT": Invalid argument > + > +ERROR: error removing device 'DEV1': Invalid argument > +Finished
On 04/09/2023 03:05, Anand Jain wrote: > > > Thanks for the test cases. These test cases might need to be updated as > per the final changes in the kernel patches. > Hi Anand, thanks a lot for the review! Very useful to me. Now, what updates are missing? I've worked this fstests case after V3 was done and tested with that. Is there any missing piece you noticed? >> [...] >> +_require_scratch_dev_pool 2 >> +_scratch_dev_pool_get 2 > > We can use > > _scratch_dev_pool_get 1 > _spare_dev_get > > So scratch devices are set to SCRATCH_DEV and SPARE_DEV. > > [...] > we can use something like: > > test_dir="${TEST_DIR}/${seq}" > scratch_mnt_copy=$test_dir/mnt_copy > >> + >> +DEV1=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $1 }') >> +DEV2=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $2 }') > Great hints, I'll change and send V2 - thanks! > > A general rule of thumb is to have one test case per file. > Well, I agree but what I'm doing in fact is testing single-dev feature in this test case, so it's self-contained and single-scoped, only single-dev stuff! I personally wouldn't see advantages having 3 tests doing almost the same thing, but if that's a requirement, I can change. > [...] >> +$MKFS_BTRFS_PROG -O single-dev $DEV1 >>$seqres.full 2>&1 > > _scratch_mkfs "-b 300m -O single-dev" > > The '-b 300m' option prevents the below 'dd' operation from taking > too long to complete on larger devices. > >> +dd if=$DEV1 of=$DEV2 bs=64M conv=fsync >> $seqres.full 2>&1 >> + > > dd if=$SCRATCH_DEV of=SPARE_DEV bs=300m count=1 conv=fsync >> > $seqres.full 2>&1 > [...] > >> +mount_btrfs $DEV1 $SCRATCH_MNT/$DIR_a >> +mount_btrfs $DEV2 $SCRATCH_MNT/$DIR_b > > > _scratch_mount > _mount $SPARE_DEV $scratch_mnt_copy > > _spare_dev_put > _scratch_dev_pool_put > > > status=0 > exit > That is very useful, will change for sure! Thanks again.
diff --git a/tests/btrfs/300 b/tests/btrfs/300 new file mode 100755 index 000000000000..120e790906ea --- /dev/null +++ b/tests/btrfs/300 @@ -0,0 +1,107 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2023 Guilherme G. Piccoli (Igalia S.L.). All Rights Reserved. +# +# FS QA Test 300 +# +# Test for the btrfs single-dev feature - both mkfs and btrfstune are +# validated, as well as explicitly unsupported commands, like device +# removal / replacement. +# +. ./common/preamble +_begin_fstest auto mkfs quick +. ./common/filter +_supported_fs btrfs + +_require_btrfs_mkfs_feature single-dev +_require_btrfs_fs_feature single_dev + +_require_scratch_dev_pool 2 +_scratch_dev_pool_get 2 + +_require_command "$BTRFS_TUNE_PROG" btrfstune +_require_command "$WIPEFS_PROG" wipefs + +# Used random hash to avoid name collision. +DIR_a="563b01de1f_a" +DIR_b="563b01de1f_b" + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* + rm -rf $SCRATCH_MNT/$DIR_a + rm -rf $SCRATCH_MNT/$DIR_b +} + +# Helper to mount a btrfs fs +# Arg 1: device +# Arg 2: mount point +mount_btrfs() +{ + $MOUNT_PROG -t btrfs $1 $2 + [ $? -ne 0 ] && _fail "mounting $1 on $2 failed" +} + +mkdir $SCRATCH_MNT/$DIR_a +mkdir $SCRATCH_MNT/$DIR_b + +DEV1=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $1 }') +DEV2=$(echo $SCRATCH_DEV_POOL | $AWK_PROG '{ print $2 }') + + +# Part 1 +# First test involves a mkfs with single-dev feature enabled. +# If it succeeds and mounting that FS *twice* also succeeds, +# we're good and continue. +$WIPEFS_PROG -a $DEV1 >> $seqres.full 2>&1 +$WIPEFS_PROG -a $DEV2 >> $seqres.full 2>&1 + +$MKFS_BTRFS_PROG -O single-dev $DEV1 >>$seqres.full 2>&1 +dd if=$DEV1 of=$DEV2 bs=64M conv=fsync >> $seqres.full 2>&1 + +mount_btrfs $DEV1 $SCRATCH_MNT/$DIR_a +mount_btrfs $DEV2 $SCRATCH_MNT/$DIR_b + +$UMOUNT_PROG $SCRATCH_MNT/$DIR_b +$UMOUNT_PROG $SCRATCH_MNT/$DIR_a + + +# Part 2 +# Second test is similar to the first with the difference we +# run mkfs with no single-dev mention, and make use of btrfstune +# to set such feature. +$WIPEFS_PROG -a $DEV1 >> $seqres.full 2>&1 +$WIPEFS_PROG -a $DEV2 >> $seqres.full 2>&1 + +$MKFS_BTRFS_PROG $DEV1 >>$seqres.full 2>&1 +$BTRFS_TUNE_PROG --convert-to-single-device $DEV1 +dd if=$DEV1 of=$DEV2 bs=64M conv=fsync >> $seqres.full 2>&1 + +mount_btrfs $DEV1 $SCRATCH_MNT/$DIR_a +mount_btrfs $DEV2 $SCRATCH_MNT/$DIR_b + +$UMOUNT_PROG $SCRATCH_MNT/$DIR_b +$UMOUNT_PROG $SCRATCH_MNT/$DIR_a + + +# Part 3 +# Final part attempts to run some single-dev unsupported commands, +# like device replace/remove - it they fail, test succeeds! +mount_btrfs $DEV1 $SCRATCH_MNT + +$BTRFS_UTIL_PROG device replace start $DEV1 $DEV1 $SCRATCH_MNT 2>&1 \ + | _filter_scratch + +$BTRFS_UTIL_PROG device remove $DEV1 $SCRATCH_MNT 2>&1 \ + | sed -e "s,\B$DEV1,DEV1,g" + +$UMOUNT_PROG $SCRATCH_MNT +_scratch_dev_pool_put 2 + +# success, all done +status=0 +echo "Finished" + +exit diff --git a/tests/btrfs/300.out b/tests/btrfs/300.out new file mode 100644 index 000000000000..5f13cfb228fb --- /dev/null +++ b/tests/btrfs/300.out @@ -0,0 +1,5 @@ +QA output created by 300 +ERROR: ioctl(DEV_REPLACE_STATUS) failed on "SCRATCH_MNT": Invalid argument + +ERROR: error removing device 'DEV1': Invalid argument +Finished
The SINGLE_DEV btrfs feature allows to mount the same filesystem multiple times, at the same time. This is the fstests counter-part, which checks both mkfs/btrfstune (by mounting the FS twice), and also unsupported scenarios, like device replace / remove. Suggested-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com> --- Hi folks, this test was a suggestion by Josef for the SINGLE_DEV feature we're trying to introduce in the kernel [0]. Some design decisions: (a) The number 300 was selected since seems we already skipped 298 in the code base, given that the test btrfs/298 is being worked upstream. (b) About mounting twice the same filesystem - how to accomplish that in a proper fashion? I went with the naive / trivial approach, just created temporary directories on top of $SCRATCH_MNT, but I'm not sure if that is the way to go. Is it guaranteed that $SCRATCH_MNT is writable prior to any mount command? (c) The way to be sure we have two different devices holding the same image was using SCRATCH_DEV_POOL and dd'ing the first device to the 2nd one - is there any better alternative than this one? Suggestions / reviews much appreciated! Cheers, Guilherme [0] https://lore.kernel.org/linux-btrfs/20230803154453.1488248-1-gpiccoli@igalia.com/ tests/btrfs/300 | 107 ++++++++++++++++++++++++++++++++++++++++++++ tests/btrfs/300.out | 5 +++ 2 files changed, 112 insertions(+) create mode 100755 tests/btrfs/300 create mode 100644 tests/btrfs/300.out