Whamcloud - gitweb
LU-13453 osd-ldiskfs: do not leak inode if OI insertion fails
[fs/lustre-release.git] / lustre / tests / sanity-scrub.sh
index 24c81a9..97d3e36 100644 (file)
@@ -7,16 +7,18 @@
 set -e
 
 ONLY=${ONLY:-"$*"}
+
+LUSTRE=${LUSTRE:-$(dirname $0)/..}
+. $LUSTRE/tests/test-framework.sh
+init_test_env $@
+init_logging
+
 ALWAYS_EXCEPT="$SANITY_SCRUB_EXCEPT"
 
 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
-LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
-. $LUSTRE/tests/test-framework.sh
-init_test_env $@
-. ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
-init_logging
+build_test_filter
 
 require_dsh_mds || exit 0
 
@@ -27,7 +29,7 @@ if ! check_versions; then
        exit 0
 fi
 
-stopall
+cleanupall
 
 SAVED_MDSSIZE=${MDSSIZE}
 SAVED_OSTSIZE=${OSTSIZE}
@@ -36,21 +38,17 @@ SAVED_OSTCOUNT=${OSTCOUNT}
 # use small MDS + OST size to speed formatting time
 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
 # 400M MDT device can guarantee uninitialized groups during the OI scrub
-MDSSIZE=400000
-OSTSIZE=200000
+[[ $MDSSIZE < 400000 || "$mds1_FSTYPE" == ldiskfs ]] && MDSSIZE=400000
+[[ $OSTSIZE < 400000 || "$ost1_FSTYPE" == ldiskfs ]] && OSTSIZE=400000
 
 # no need too many OSTs, to reduce the format/start/stop overhead
 [ $OSTCOUNT -gt 4 ] && OSTCOUNT=4
 
 # build up a clean test environment.
-formatall
-setupall
-
-build_test_filter
+REFORMAT="yes" check_and_setup_lustre
 
 MDT_DEV="${FSNAME}-MDT0000"
 OST_DEV="${FSNAME}-OST0000"
-MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
 
 scrub_start() {
        local error_id=$1
@@ -101,14 +99,16 @@ scrub_prep() {
        echo "preparing... $(date)"
        for n in $(seq $MDSCOUNT); do
                echo "creating $nfiles files on mds$n"
-               test_mkdir -i $((n - 1)) $DIR/$tdir/mds$n ||
+               test_mkdir -i $((n - 1)) -c1 $DIR/$tdir/mds$n ||
                        error "Failed to create directory mds$n"
                cp $LUSTRE/tests/*.sh $DIR/$tdir/mds$n ||
                        error "Failed to copy files to mds$n"
                mkdir -p $DIR/$tdir/mds$n/d_$tfile ||
                        error "mkdir failed on mds$n"
-               createmany -m $DIR/$tdir/mds$n/d_$tfile/f 2 > \
+               touch $DIR/$tdir/mds$n/d_$tfile/f1 > \
                        /dev/null || error "create failed on mds$n"
+               dd if=/dev/zero of=$DIR/$tdir/mds$n/d_$tfile/f2 bs=1M count=1 ||
+                       error "write failed on mds$n"
                if [[ $nfiles -gt 0 ]]; then
                        createmany -m $DIR/$tdir/mds$n/$tfile $nfiles > \
                                /dev/null || error "createmany failed on mds$n"
@@ -130,7 +130,7 @@ scrub_prep() {
        }
 
        [ ! -z $inject ] && [ $inject -eq 1 ] &&
-               [ $(facet_fstype $SINGLEMDS) = "zfs" ] && {
+               [ "$mds1_FSTYPE" = "zfs" ] && {
                #define OBD_FAIL_OSD_FID_MAPPING        0x193
                do_nodes $(comma_list $(mdts_nodes)) \
                        $LCTL set_param fail_loc=0x193
@@ -161,7 +161,7 @@ scrub_prep() {
                stop mds$n > /dev/null || error "Fail to stop MDS$n!"
        done
 
-       [ ! -z $inject ] && [ $(facet_fstype $SINGLEMDS) = "ldiskfs" ] && {
+       [ ! -z $inject ] && [ "$mds1_FSTYPE" = "ldiskfs" ] && {
                if [ $inject -eq 1 ]; then
                        for n in $(seq $MDSCOUNT); do
                                mds_backup_restore mds$n ||
@@ -296,7 +296,7 @@ scrub_check_data2() {
 }
 
 scrub_remove_ois() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && return
 
        local error_id=$1
        local index=$2
@@ -314,7 +314,7 @@ scrub_enable_auto() {
 }
 
 full_scrub_ratio() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && return
 
        local ratio=$1
 
@@ -323,7 +323,7 @@ full_scrub_ratio() {
 }
 
 full_scrub_threshold_rate() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && return
 
        local rate=$1
 
@@ -353,6 +353,8 @@ test_0() {
 run_test 0 "Do not auto trigger OI scrub for non-backup/restore case"
 
 test_1a() {
+       [ -n "$FILESET" ] && skip "Not functional for FILESET set"
+
        scrub_prep 0
        echo "start $SINGLEMDS without disabling OI scrub"
        scrub_start_mds 1 "$MOUNT_OPTS_SCRUB"
@@ -372,7 +374,7 @@ test_1a() {
        stop $SINGLEMDS > /dev/null || error "(6) Fail to stop MDS!"
 
        echo "start $SINGLEMDS with disabling OI scrub"
-       start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
+       start $SINGLEMDS $(mdsdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
                error "(7) Fail to start MDS!"
 
        local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
@@ -385,7 +387,7 @@ test_1b() {
        scrub_prep 0 2
        echo "start MDTs without disabling OI scrub"
        scrub_start_mds 2 "$MOUNT_OPTS_SCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_status 3 completed
        mount_client $MOUNT || error "(4) Fail to start client!"
        scrub_check_data2 runas 5
@@ -394,8 +396,8 @@ test_1b() {
 run_test 1b "Trigger OI scrub when MDT mounts for OI files remove/recreate case"
 
 test_1c() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        local index
 
@@ -417,8 +419,8 @@ test_1c() {
 run_test 1c "Auto detect kinds of OI file(s) removed/recreated cases"
 
 test_2() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        scrub_prep 0 1
        echo "starting MDTs without disabling OI scrub"
@@ -438,7 +440,7 @@ test_3() {
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
        scrub_check_status 3 init
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
 }
 #run_test 3 "Do not trigger OI scrub when MDT mounts if 'noscrub' specified"
@@ -447,7 +449,7 @@ test_4a() {
        scrub_prep 0 1
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
        mount_client $MOUNT || error "(5) Fail to start client!"
        scrub_enable_auto
@@ -478,8 +480,8 @@ test_4a() {
 run_test 4a "Auto trigger OI scrub if bad OI mapping was found (1)"
 
 test_4b() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        scrub_prep 5 1
        echo "starting MDTs with OI scrub disabled"
@@ -565,8 +567,8 @@ test_4b() {
 run_test 4b "Auto trigger OI scrub if bad OI mapping was found (2)"
 
 test_4c() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        scrub_prep 500 1
        echo "starting MDTs with OI scrub disabled"
@@ -651,6 +653,28 @@ test_4c() {
 }
 run_test 4c "Auto trigger OI scrub if bad OI mapping was found (3)"
 
+test_4d() {
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
+
+       check_mount_and_prep
+
+       #define OBD_FAIL_OSD_DUPLICATE_MAP      0x19b
+       do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x19b
+       for i in {1..100}; do
+               echo $i > $DIR/$tdir/f_$i || error "write f_$i failed"
+       done
+       do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
+
+       for i in {101..200}; do
+               echo $i > $DIR/$tdir/f_$i || error "write f_$i failed"
+       done
+
+       for i in {1..200}; do
+               echo $i | cmp $DIR/$tdir/f_$i - || error "f_$i data corrupt"
+       done
+}
+run_test 4d "FID in LMA mismatch with object FID won't block create"
+
 test_5() {
        formatall > /dev/null
        setupall > /dev/null
@@ -659,7 +683,7 @@ test_5() {
        echo "starting MDTs with OI scrub disabled (1)"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
        scrub_check_status 3 init
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
        mount_client $MOUNT || error "(5) Fail to start client!"
        scrub_enable_auto
@@ -727,7 +751,7 @@ test_6() {
        scrub_prep 100 1
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
        mount_client $MOUNT || error "(5) Fail to start client!"
        scrub_enable_auto
@@ -805,7 +829,7 @@ test_7() {
        scrub_prep 500 1
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
        mount_client $MOUNT || error "(5) Fail to start client!"
        scrub_enable_auto
@@ -824,7 +848,7 @@ test_7() {
        done
 
        scrub_check_status 8 scanning
-       if [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ]; then
+       if [ "$mds1_FSTYPE" != "ldiskfs" ]; then
                scrub_check_flags 9 inconsistent,auto
        else
                scrub_check_flags 9 recreated,inconsistent,auto
@@ -842,7 +866,7 @@ test_8() {
        scrub_prep 128 1
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
 
        #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
@@ -866,12 +890,11 @@ run_test 8 "Control OI scrub manually"
 
 test_9() {
        # Skip scrub speed test for ZFS because of performance unstable
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "test scrub speed only on ldiskfs" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "test scrub speed only on ldiskfs"
 
        if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
                skip "Testing on UP system, the speed may be inaccurate."
-               return 0
        fi
 
        scrub_prep 6000 1
@@ -951,7 +974,7 @@ test_10a() {
        scrub_prep 0 1
        echo "starting mds$n with OI scrub disabled (1)"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
        mount_client $MOUNT || error "(5) Fail to start client!"
        scrub_enable_auto
@@ -986,7 +1009,7 @@ test_10b() {
        scrub_prep 0 1
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
 
        #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
@@ -1013,8 +1036,8 @@ test_10b() {
 #run_test 10b "non-stopped OI scrub should auto restarts after MDS remount (2)"
 
 test_11() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        local CREATED=100
        local n
@@ -1022,7 +1045,7 @@ test_11() {
        check_mount_and_prep
 
        for n in $(seq $MDSCOUNT); do
-               test_mkdir -i $((n - 1)) $DIR/$tdir/mds$n ||
+               test_mkdir -i $((n - 1)) -c1 $DIR/$tdir/mds$n ||
                        error "(1) Fail to mkdir $DIR/$tdir/mds$n"
 
                createmany -o $DIR/$tdir/mds$n/f $CREATED ||
@@ -1068,7 +1091,7 @@ run_test 11 "OI scrub skips the new created objects only once"
 
 test_12() {
        check_mount_and_prep
-       $SETSTRIPE -c 1 -i 0 $DIR/$tdir
+       $LFS setstripe -c 1 -i 0 $DIR/$tdir
 
        #define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY               0x195
        do_facet ost1 $LCTL set_param fail_loc=0x195
@@ -1106,7 +1129,7 @@ run_test 12 "OI scrub can rebuild invalid /O entries"
 
 test_13() {
        check_mount_and_prep
-       $SETSTRIPE -c 1 -i 0 $DIR/$tdir
+       $LFS setstripe -c 1 -i 0 $DIR/$tdir
 
        #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
        do_facet ost1 $LCTL set_param fail_loc=0x196
@@ -1138,11 +1161,11 @@ test_13() {
 run_test 13 "OI scrub can rebuild missed /O entries"
 
 test_14() {
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
-               skip "ldiskfs special test" && return
+       [ "$mds1_FSTYPE" != "ldiskfs" ] &&
+               skip "ldiskfs special test"
 
        check_mount_and_prep
-       $SETSTRIPE -c 1 -i 0 $DIR/$tdir
+       $LFS setstripe -c 1 -i 0 $DIR/$tdir
 
        #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
        do_facet ost1 $LCTL set_param fail_loc=0x196
@@ -1165,13 +1188,19 @@ test_14() {
        mount_client $MOUNT || error "(5) Fail to start client!"
 
        local LF_REPAIRED=$($SHOW_SCRUB_ON_OST |
-                           awk '/^lf_repa[ri]*ed/ { print $2 }')
+                           awk '/^lf_repa[ir]*ed/ { print $2 }')
        [ $LF_REPAIRED -ge 1000 ] ||
                error "(6) Some entry under /lost+found should be repaired"
 
        ls -ail $DIR/$tdir > /dev/null || error "(7) ls should succeed"
+
+       stopall
+
+       echo "run e2fsck again after LFSCK"
+       run_e2fsck $(facet_host ost1) $(ostdevname 1) "-y" ||
+               error "(8) Fail to run e2fsck error"
 }
-run_test 14 "OI scrub can repair objects under lost+found"
+run_test 14 "OI scrub can repair OST objects under lost+found"
 
 test_15() {
        local repaired
@@ -1183,13 +1212,13 @@ test_15() {
        echo "starting MDTs with OI scrub disabled"
        scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
        scrub_check_status 3 init
-       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] ||
+       [ "$mds1_FSTYPE" != "ldiskfs" ] ||
                scrub_check_flags 4 recreated,inconsistent
 
        # run under dryrun mode
        scrub_start 5 --dryrun
        scrub_check_status 6 completed
-       if [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ]; then
+       if [ "$mds1_FSTYPE" != "ldiskfs" ]; then
                scrub_check_flags 7 inconsistent
                repaired=2
        else
@@ -1202,7 +1231,7 @@ test_15() {
        # run under dryrun mode again
        scrub_start 10 --dryrun
        scrub_check_status 11 completed
-       if [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ]; then
+       if [ "$mds1_FSTYPE" != "ldiskfs" ]; then
                scrub_check_flags 12 inconsistent
        else
                scrub_check_flags 12 recreated,inconsistent
@@ -1243,13 +1272,45 @@ test_16() {
 }
 run_test 16 "Initial OI scrub can rebuild crashed index objects"
 
+test_17a() {
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
+
+#define OBD_FAIL_OSD_OI_ENOSPC                         0x19d
+       do_facet mds1 $LCTL set_param fail_loc=0x8000019d
+       mkdir $DIR/$tdir && error "mkdir should fail"
+       stop mds1
+       local devname=$(mdsdevname 1)
+
+       stack_trap "start mds1 $devname $MDS_MOUNT_OPTS" EXIT
+       FSCK_MAX_ERR=0 run_e2fsck $(facet_active_host mds1) $devname -n ||
+               error "e2fsck returned $?"
+}
+run_test 17a "ENOSPC on OI insert shouldn't leak inodes"
+
+test_17b() {
+       [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
+
+#define OBD_FAIL_OSD_DOTDOT_ENOSPC                     0x19e
+       do_facet mds1 $LCTL set_param fail_loc=0x8000019e
+       mkdir $DIR/$tdir && error "mkdir should fail"
+       stop mds1
+       local devname=$(mdsdevname 1)
+
+       stack_trap "start mds1 $devname $MDS_MOUNT_OPTS" EXIT
+       FSCK_MAX_ERR=0 run_e2fsck $(facet_active_host mds1) $devname -n ||
+               error "e2fsck returned $?"
+}
+run_test 17b "ENOSPC on .. insertion shouldn't leak inodes"
+
+
 # restore MDS/OST size
 MDSSIZE=${SAVED_MDSSIZE}
 OSTSIZE=${SAVED_OSTSIZE}
 OSTCOUNT=${SAVED_OSTCOUNT}
 
 # cleanup the system at last
-formatall
+REFORMAT="yes" cleanup_and_setup_lustre
 
 complete $SECONDS
+check_and_cleanup_lustre
 exit_status