From: Andreas Dilger Date: Sat, 24 Sep 2011 18:13:27 +0000 (-0400) Subject: e2fsck: regression tests for INCOMPAT_MMP feature X-Git-Tag: v1.42-WIP-0925~5 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d9c60e04b3b18b13d7707f1876ac7bce89df10e9;p=tools%2Fe2fsprogs.git e2fsck: regression tests for INCOMPAT_MMP feature Add tests for the MMP feature - creating a filesystem with mke2fs and MMP enabled, enable/disable MMP with tune2fs, disabling the e2fsck MMP flag with tune2fs after a failed e2fsck, and e2fsck checking and fixing a corrupt MMP block. The MMP tests need to be run from a real disk, not tmpfs, because tmpfs doesn't support O_DIRECT reads, which MMP uses to ensure that reads from the MMP block are not filled from the page cache. Using a local disk does not slow down the tests noticably, since they wait to detect if the MMP block is being modified. Signed-off-by: Andreas Dilger Signed-off-by: "Theodore Ts'o" --- diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index a317ce9..76c529d 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -543,9 +543,9 @@ future. only supports clearing this filesystem feature. .TP .B mmp -Enable or disable multiple mount protection(MMP) feature. MMP helps to protect -the filesystem from being multiply mounted and is useful in shared storage -environments. +Enable or disable multiple mount protection (MMP) feature. MMP helps to +protect the filesystem from being multiply mounted and is useful in +shared storage environments. .TP .B sparse_super Limit the number of backup superblocks to save space on large filesystems. diff --git a/tests/f_mmp/name b/tests/f_mmp/name new file mode 100644 index 0000000..20d66d6 --- /dev/null +++ b/tests/f_mmp/name @@ -0,0 +1 @@ +disable MMP with tune2fs after e2fsck killed diff --git a/tests/f_mmp/script b/tests/f_mmp/script new file mode 100644 index 0000000..548734a --- /dev/null +++ b/tests/f_mmp/script @@ -0,0 +1,67 @@ +FSCK_OPT=-yf + +TMPFILE=test.img +rm -f $test_name.failed $test_name.ok +> $TMPFILE + +stat -f $TMPFILE | grep -q "Type: tmpfs" +if [ $? == 0 ]; then + rm -f $TMPFILE + echo "skipped for tmpfs (no O_DIRECT support)" + return 0 +fi + +echo "make the test image ..." > $test_name.log +$MKE2FS -q -F -o Linux -b 1024 -O mmp -E mmp_update_interval=1 $TMPFILE 100 >> $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "mke2fs -O mmp failed" > $test_name.failed + echo "failed" + return $status +fi + +# this will cause debugfs to create the $test_name.mark file once it has +# passed the MMP startup, then continue reading input until it is killed +MARKFILE=$test_name.new +rm -f $MARKFILE +echo "set mmp sequence to EXT2_MMP_SEQ_FSCK..." >> $test_name.log +( { echo dump_mmp; echo "dump_inode <2> $MARKFILE"; cat /dev/zero; } | + $DEBUGFS -w $TMPFILE >> $test_name.log 2>&1 & ) > /dev/null 2>&1 & +echo "wait until debugfs has started ..." >> $test_name.log +while [ ! -e $MARKFILE ]; do + sleep 1 +done +rm -f $MARKFILE +echo "kill debugfs abruptly (simulates e2fsck failure) ..." >> $test_name.log +killall -9 debugfs >> $test_name.log + + +echo "e2fsck (should fail mmp_seq = EXT2_MMP_SEQ_FSCK) ..." >> $test_name.log +$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1 +status=$? +if [ "$status" == 0 ] ; then + echo "e2fsck with MMP as EXT2_MMP_SEQ_FSCK ran!" > $test_name.failed + echo "failed" + return 1 +fi + +echo "clear mmp_seq with tune2fs ..." >> $test_name.log +$TUNE2FS -f -E clear_mmp $TMPFILE >> $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "tune2fs clearing EXT2_MMP_SEQ_FSCK failed" > $test_name.failed + echo "failed" + return 1 +fi + +echo "run e2fsck again (should pass with clean mmp_seq) ..." >> $test_name.log +$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "e2fsck after clearing EXT2_MMP_SEQ_FSCK failed"> $test_name.failed + echo "failed" + return $status +fi + +echo "ok" +rm -f $TMPFILE diff --git a/tests/f_mmp_garbage/expect.1 b/tests/f_mmp_garbage/expect.1 new file mode 100644 index 0000000..4ee5cfb --- /dev/null +++ b/tests/f_mmp_garbage/expect.1 @@ -0,0 +1,9 @@ +Superblock has invalid MMP magic. Fix? yes + +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 0 diff --git a/tests/f_mmp_garbage/expect.2 b/tests/f_mmp_garbage/expect.2 new file mode 100644 index 0000000..3bf3869 --- /dev/null +++ b/tests/f_mmp_garbage/expect.2 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 0 diff --git a/tests/f_mmp_garbage/name b/tests/f_mmp_garbage/name new file mode 100644 index 0000000..17e0b14 --- /dev/null +++ b/tests/f_mmp_garbage/name @@ -0,0 +1 @@ +repair MMP when it is corrupted diff --git a/tests/f_mmp_garbage/script b/tests/f_mmp_garbage/script new file mode 100644 index 0000000..3c80032 --- /dev/null +++ b/tests/f_mmp_garbage/script @@ -0,0 +1,28 @@ +FSCK_OPT=-yf + +TMPFILE=test.img +rm -f $test_name.failed $test_name.ok +> $TMPFILE + +stat -f $TMPFILE | grep -q "Type: tmpfs" +if [ $? == 0 ] ; then + rm -f $TMPFILE + echo "skipped for tmpfs (no O_DIRECT support)" + return 0 +fi + +echo "make the test image ..." > $test_name.log +$MKE2FS -q -F -o Linux -b 1024 -O mmp -E mmp_update_interval=1 $TMPFILE 100 >> $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "mke2fs -O mmp failed" > $test_name.failed + echo "failed" + return $status +fi + +# create a corrupted image +echo "modify the mmp sequence ..." >> $test_name.log +$DEBUGFS -w -R "set_mmp_value magic 0x12345678" $TMPFILE >> $test_name.log 2>&1 + +SKIP_GUNZIP=true +. $cmd_dir/run_e2fsck diff --git a/tests/m_mmp/expect.1 b/tests/m_mmp/expect.1 new file mode 100644 index 0000000..3a00815 --- /dev/null +++ b/tests/m_mmp/expect.1 @@ -0,0 +1,79 @@ +Filesystem label= +OS type: Linux +Block size=2048 (log=1) +Fragment size=2048 (log=1) +Stride=0 blocks, Stripe width=0 blocks +16384 inodes, 32768 blocks +1638 blocks (5.00%) reserved for the super user +First data block=0 +Maximum filesystem blocks=33554432 +2 block groups +16384 blocks per group, 16384 fragments per group +8192 inodes per group +Superblock backups stored on blocks: + 16384 + +Allocating group tables: 0/21/2 done +Writing inode tables: 0/21/2 done +Multiple mount protection is enabled with update interval 5 seconds. +Writing superblocks and filesystem accounting information: 0/21/2 done + +Filesystem features: ext_attr resize_inode dir_index filetype mmp sparse_super + +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/16384 files (0.0% non-contiguous), 1105/32768 blocks +Exit status is 0 + +Filesystem volume name: +Last mounted on: +Filesystem magic number: 0xEF53 +Filesystem revision #: 1 (dynamic) +Filesystem features: ext_attr resize_inode dir_index filetype mmp sparse_super +Default mount options: (none) +Filesystem state: clean +Errors behavior: Continue +Filesystem OS type: Linux +Inode count: 16384 +Block count: 32768 +Reserved block count: 1638 +Free blocks: 31663 +Free inodes: 16373 +First block: 0 +Block size: 2048 +Fragment size: 2048 +Reserved GDT blocks: 31 +Blocks per group: 16384 +Fragments per group: 16384 +Inodes per group: 8192 +Inode blocks per group: 512 +Mount count: 0 +Check interval: 15552000 (6 months) +Reserved blocks uid: 0 +Reserved blocks gid: 0 +First inode: 11 +Inode size: 128 +Default directory hash: half_md4 +MMP block number: 557 +MMP update interval: 5 + + +Group 0: (Blocks 0-16383) + Primary superblock at 0, Group descriptors at 1-1 + Reserved GDT blocks at 2-32 + Block bitmap at 33 (+33), Inode bitmap at 34 (+34) + Inode table at 35-546 (+35) + 15826 free blocks, 8181 free inodes, 2 directories + Free blocks: 558-16383 + Free inodes: 12-8192 +Group 1: (Blocks 16384-32767) + Backup superblock at 16384, Group descriptors at 16385-16385 + Reserved GDT blocks at 16386-16416 + Block bitmap at 16417 (+33), Inode bitmap at 16418 (+34) + Inode table at 16419-16930 (+35) + 15837 free blocks, 8192 free inodes, 0 directories + Free blocks: 16931-32767 + Free inodes: 8193-16384 diff --git a/tests/m_mmp/script b/tests/m_mmp/script new file mode 100644 index 0000000..1547463 --- /dev/null +++ b/tests/m_mmp/script @@ -0,0 +1,15 @@ +DESCRIPTION="enable MMP during mke2fs" +FS_SIZE=65536 +MKE2FS_DEVICE_SECTSIZE=2048 +export MKE2FS_DEVICE_SECTSIZE +TMPFILE=test.img +> $TMPFILE +stat -f $TMPFILE | grep -q "Type: tmpfs" +if [ $? == 0 ]; then + rm -f $TMPFILE + echo "skipped for tmpfs (no O_DIRECT support)" + return 0 +fi +MKE2FS_OPTS="-O mmp" +. $cmd_dir/run_mke2fs +unset MKE2FS_DEVICE_SECTSIZE diff --git a/tests/t_mmp_1on/name b/tests/t_mmp_1on/name new file mode 100644 index 0000000..62e16b2 --- /dev/null +++ b/tests/t_mmp_1on/name @@ -0,0 +1 @@ +enable MMP using tune2fs diff --git a/tests/t_mmp_1on/script b/tests/t_mmp_1on/script new file mode 100644 index 0000000..ee9884f --- /dev/null +++ b/tests/t_mmp_1on/script @@ -0,0 +1,40 @@ +FSCK_OPT=-yf + +TMPFILE=test.img +rm -f $test_name.failed $test_name.ok +> $TMPFILE + +stat -f $TMPFILE | grep -q "Type: tmpfs" +if [ $? == 0 ] ; then + rm -f $TMPFILE + echo "skipped for tmpfs (no O_DIRECT support)" + return 0 +fi + +$MKE2FS -q -F -o Linux -b 1024 $TMPFILE 100 > $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "mke2fs failed" > $test_name.failed + echo "failed" + return $status +fi + +$TUNE2FS -O mmp -E mmp_update_interval=1 $TMPFILE >> $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "tune2fs -O mmp failed with $status" > $test_name.failed + echo "failed" + return $status +fi + +$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1 +status=$? +if [ "$status" = 0 ] ; then + echo "ok" + touch $test_name.ok +else + echo "e2fsck with MMP enabled failed with $status" > $test_name.failed + echo "failed" + return $status +fi +rm -f $TMPFILE diff --git a/tests/t_mmp_2off/name b/tests/t_mmp_2off/name new file mode 100644 index 0000000..d7cac51 --- /dev/null +++ b/tests/t_mmp_2off/name @@ -0,0 +1 @@ +disable MMP using tune2fs diff --git a/tests/t_mmp_2off/script b/tests/t_mmp_2off/script new file mode 100644 index 0000000..ec9f71e --- /dev/null +++ b/tests/t_mmp_2off/script @@ -0,0 +1,40 @@ +FSCK_OPT=-yf + +TMPFILE=test.img +rm -f $test_name.failed $test_name.ok +> $TMPFILE + +stat -f $TMPFILE | grep -q "Type: tmpfs" +if [ $? == 0 ]; then + rm -f $TMPFILE + echo "skipped for tmpfs (no O_DIRECT support)" + return 0 +fi + +$MKE2FS -q -F -o Linux -b 1024 -O mmp $TMPFILE 100 > $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "mke2fs -O mmp failed" > $test_name.failed + echo "failed" + return $status +fi + +$TUNE2FS -O ^mmp $TMPFILE > $test_name.log 2>&1 +status=$? +if [ "$status" != 0 ] ; then + echo "tune2fs -O ^mmp failed" > $test_name.failed + echo "failed" + return $status +fi + +$FSCK $FSCK_OPT $TMPFILE > $test_name.log 2>&1 +status=$? +if [ "$status" = 0 ] ; then + echo "ok" + touch $test_name.ok +else + echo "e2fsck after MMP disable failed" > $test_name.failed + echo "failed" + return $status +fi +rm -f $TMPFILE