-if [ "$LFSCK_SETUP" != "no" ]; then
- #Create test directory
- # -- can't remove the mountpoint...
- [ -z "$DIR" ] && rm -rf $DIR/*
- mkdir -p $DIR
- OSTCOUNT=`$LFS osts | grep -c "^[0-9]*: " || true`
-
- # Create some files on the filesystem
- for d in `seq -f d%g $NUMDIRS`; do
- echo "creating files in $DIR/$d"
- for e in `seq -f d%g $NUMDIRS`; do
- mkdir -p $DIR/$d/$e
- for f in `seq -f test%g $NUMDIRS`; do
- cp /etc/fstab $DIR/$d/$e/$f ||exit 5
- done
- done
- done
-
- # Create Files to be modified
- for f in `seq -f $DIR/testfile.%g $((NUMFILES * 3))`; do
- echo "creating $f"
- cp /etc/termcap $f || exit 10
- done
-
- #Create some more files
- for d in `seq -f d%g $((NUMDIRS * 2 + 1)) $((NUMDIRS * 2 + 3))`; do
- echo "creating files in $DIR/$d"
- for e in `seq -f d%g $NUMDIRS`; do
- mkdir -p $DIR/$d/$e
- for f in `seq -f test%g $NUMDIRS`; do
- cp /etc/hosts $DIR/$d/$e/$f ||exit 15
- done
- done
- done
-
- # these should NOT be taken as duplicates
- for f in `seq -f $DIR/$d/linkfile.%g $NUMFILES`; do
- echo "linking files in $DIR/$d"
- cp /etc/hosts $f
- ln $f $f.link
- done
-
- # Get objids for a file on the OST
- OST_FILES=`seq -f $DIR/testfile.%g $NUMFILES`
- OST_REMOVE=`$GETSTRIPE $OST_FILES | awk '$1 == 0 { print $2 }' | head -n $NUMFILES`
-
- export MDS_DUPE=""
- for f in `seq -f testfile.%g $((NUMFILES + 1)) $((NUMFILES * 2))`; do
- TEST_FILE=$DIR/$f
- echo "DUPLICATING MDS file $TEST_FILE"
- $GETSTRIPE -v $TEST_FILE >> $LOG || exit 20
- MDS_DUPE="$MDS_DUPE $TEST_FILE"
- done
- MDS_DUPE=`echo $MDS_DUPE | sed "s#$MOUNT/##g"`
-
- export MDS_REMOVE=""
- for f in `seq -f testfile.%g $((NUMFILES * 2 + 1)) $((NUMFILES * 3))`; do
- TEST_FILE=$DIR/$f
- echo "REMOVING MDS file $TEST_FILE which has info:"
- $GETSTRIPE -v $TEST_FILE >> $LOG || exit 30
- MDS_REMOVE="$MDS_REMOVE $TEST_FILE"
- done
- MDS_REMOVE=`echo $MDS_REMOVE | sed "s#$MOUNT/##g"`
-
- MDTDEVS=`get_mnt_devs mds`
- OSTDEVS=`get_mnt_devs obdfilter`
- OSTCOUNT=`echo $OSTDEVS | wc -w`
- sh llmountcleanup.sh || exit 40
-
- # Remove objects associated with files
- echo "removing objects: `echo $OST_REMOVE`"
- DEBUGTMP=`mktemp $TMP/debugfs.XXXXXXXXXX`
- for i in $OST_REMOVE; do
- echo "rm O/0/d$((i % 32))/$i" >> $DEBUGTMP
- done
- $DEBUGFS -w -f $DEBUGTMP `echo $OSTDEVS | cut -d' ' -f 1`
- RET=$?
- rm $DEBUGTMP
- [ $RET -ne 0 ] && exit 50
-
- SAVE_PWD=$PWD
- [ "$FSTYPE" = "ldiskfs" ] && load_module ../ldiskfs/ldiskfs/ldiskfs
- mount -t $FSTYPE -o loop $MDSDEV $MOUNT || exit 60
- do_umount() {
- trap 0
- cd $SAVE_PWD
- umount -f $MOUNT
- }
- trap do_umount EXIT
-
- #Remove files from mds
- for f in $MDS_REMOVE; do
- rm $MOUNT/ROOT/$f || exit 70
- done
-
- #Create EAs on files so objects are referenced from different files
- ATTRTMP=`mktemp $TMP/setfattr.XXXXXXXXXX`
- cd $MOUNT/ROOT || exit 78
- for f in $MDS_DUPE; do
- touch $f.bad || exit 74
- getfattr -n trusted.lov $f | sed "s#$f#&.bad#" > $ATTRTMP
- setfattr --restore $ATTRTMP || exit 80
- done
- cd $SAVE_PWD
- rm $ATTRTMP
-
- do_umount
-else
- MDTDEVS=`get_mnt_devs mds`
- OSTDEVS=`get_mnt_devs obdfilter`
- OSTCOUNT=`echo $OSTDEVS | wc -w`
-fi # LFSCK_SETUP
-
-# Run e2fsck to get mds and ost info
-# a return status of 1 indicates e2fsck successfuly fixed problems found
-set +e
-
-echo "$E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV"
-df > /dev/null # update statfs data on disk
-$E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV
-RET=$?
-[ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 90 || true
-
-export OSTDB_LIST=""
-i=0
-for OSTDEV in $OSTDEVS; do
- df > /dev/null # update statfs data on disk
- $E2FSCK -d -v -fn --mdsdb $MDSDB --ostdb $OSTDB-$i $OSTDEV
- RET=$?
- [ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 100
- OSTDB_LIST="$OSTDB_LIST $OSTDB-$i"
- i=$((i + 1))
-done
-
-#Remount filesystem
-[ "`mount | grep $MOUNT`" ] || setupall
-
-# need to turn off shell error detection to get proper error return
+# Get the file names to be duplicated or removed on the MDS.
+get_files() {
+ local flavor=$1
+ local test_dir=$2
+ local num_files=$3
+ local first last
+ local test_file
+
+ case $flavor in
+ dup)
+ first=$((num_files + 1))
+ last=$((num_files * 2))
+ ;;
+ remove)
+ first=$((num_files * 2 + 1))
+ last=$((num_files * 3))
+ ;;
+ *) echo "get_files(): invalid flavor" && return 1 ;;
+ esac
+
+ local files=""
+ local f
+ for f in $(seq -f testfile.%g $first $last); do
+ test_file=$test_dir/$f
+ files="$files $test_file"
+ done
+ files=$(echo $files | sed "s#$DIR/##g")
+ echo $files
+}
+
+# Remove objects associated with files.
+remove_objects() {
+ local node=$1
+ shift
+ local ostdev=$1
+ shift
+ local group=$1
+ shift
+ local objids="$@"
+ local tmp
+ local i
+ local rc
+
+ echo "removing objects from $ostdev on $facet: $objids"
+ tmp=$(mktemp $SHARED_DIRECTORY/debugfs.XXXXXXXXXX)
+ for i in $objids; do
+ echo "rm O/$group/d$((i % 32))/$i" >> $tmp
+ done
+
+ do_node $node "$DEBUGFS -w -f $tmp $ostdev"
+ rc=${PIPESTATUS[0]}
+ rm -f $tmp
+
+ return $rc
+}
+
+# Remove files from MDS.
+remove_files() {
+ do_rpc_nodes $(facet_host $1) remove_mdt_files $@
+}
+
+# Create EAs on files so objects are referenced from different files.
+duplicate_files() {
+ do_rpc_nodes $(facet_host $1) duplicate_mdt_files $@
+}
+
+#********************************* Main Flow **********************************#
+
+# get the server target devices
+get_svr_devs
+
+if [ "$SKIP_LFSCK" = "no" ] && is_empty_fs $MOUNT; then
+ # create test directory
+ TESTDIR=$DIR/d0.$TESTSUITE
+ mkdir -p $TESTDIR || error "mkdir $TESTDIR failed"
+
+ # create some dirs and files on the filesystem
+ create_files $TESTDIR $NUMDIRS $NUMFILES
+
+ # get the objids for files in group $OBJGRP on the OST with index $OSTIDX
+ OST_REMOVE=$(get_objects $OSTIDX $OBJGRP \
+ $(seq -f $TESTDIR/testfile.%g $NUMFILES))
+
+ # get the node name and target device for the OST with index $OSTIDX
+ OSTNODE=$(get_ost_node $OSTIDX) || error "get_ost_node by index $OSTIDX failed"
+ OSTDEV=$(get_ost_dev $OSTNODE $OSTIDX) || \
+ error "get_ost_dev $OSTNODE $OSTIDX failed"
+
+ # get the file names to be duplicated on the MDS
+ MDS_DUPE=$(get_files dup $TESTDIR $NUMFILES) || error "$MDS_DUPE"
+ # get the file names to be removed from the MDS
+ MDS_REMOVE=$(get_files remove $TESTDIR $NUMFILES) || error "$MDS_REMOVE"
+
+ stopall -f || error "cleanupall failed"
+
+ # remove objects associated with files in group $OBJGRP
+ # on the OST with index $OSTIDX
+ remove_objects $OSTNODE $OSTDEV $OBJGRP $OST_REMOVE || \
+ error "removing objects failed"
+
+ # remove files from MDS
+ remove_files mds $MDSDEV $MDS_REMOVE || error "removing files failed"
+
+ # create EAs on files so objects are referenced from different files
+ duplicate_files mds $MDSDEV $MDS_DUPE || \
+ error "duplicating files failed"
+ FSCK_MAX_ERR=1 # file system errors corrected
+else # $SKIP_LFSCK = yes || !is_empty_fs $MOUNT
+ FSCK_MAX_ERR=4 # file system errors left uncorrected
+fi
+
+# Test 1a - check and repair the filesystem