7 MDSDB=${MDSDB:-$TMP/mdsdb}
8 OSTDB=${OSTDB:-$TMP/ostdb}
9 LOG=${LOG:-"$TMP/lfscktest.log"}
10 L2FSCK_PATH=${L2FSCK_PATH:-""}
11 NUMFILES=${NUMFILES:-10}
13 GETSTRIPE=${GETSTRIPE:-"lfs getstripe"}
14 GETFATTR=${GETFATTR:-getfattr}
15 SETFATTR=${SETFATTR:-setfattr}
18 export PATH=$LFSCK_PATH:`dirname $0`:`dirname $0`/../utils:$PATH
20 [ -z "`which $GETFATTR`" ] && echo "$0: $GETFATTR not found" && exit 5
21 [ -z "`which $SETFATTR`" ] && echo "$0: $SETFATTR not found" && exit 6
23 LUSTRE=${LUSTRE:-`dirname $0`/..}
24 . $LUSTRE/tests/test-framework.sh
26 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
28 remote_mds && skip "remote MDS" && exit 0
29 remote_ost && skip "remote OST" && exit 0
31 # if nothing mounted, don't nuke MOUNT variable needed in llmount.sh
32 WAS_MOUNTED=$(mounted_lustre_filesystems | head -1)
33 if [ -z "$WAS_MOUNTED" ]; then
34 # This code doesn't handle multiple mounts well, so nuke MOUNT2 variable
35 MOUNT2="" sh llmount.sh
36 MOUNT=$(mounted_lustre_filesystems)
37 [ -z "$MOUNT" ] && echo "NAME=$NAME not mounted" && exit 2
43 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && exit 3
45 if [ "$WAS_MOUNTED" ]; then
47 MAX_ERR=4 # max expected error from e2fsck
51 DEVS=`lctl get_param -n $1.*.mntdev`
54 *loop*) losetup $DEV | sed -e "s/.*(//" -e "s/).*//" ;;
60 if [ "$LFSCK_SETUP" != "no" ]; then
61 #Create test directory
62 # -- can't remove the mountpoint...
63 [ -z "$DIR" ] && rm -rf $DIR/*
65 OSTCOUNT=`$LFS osts | grep -c "^[0-9]*: " || true`
67 # Create some files on the filesystem
68 for d in `seq -f d%g $NUMDIRS`; do
69 echo "creating files in $DIR/$d"
70 for e in `seq -f d%g $NUMDIRS`; do
72 for f in `seq -f test%g $NUMDIRS`; do
73 cp /etc/fstab $DIR/$d/$e/$f ||exit 5
78 # Create Files to be modified
79 for f in `seq -f $DIR/testfile.%g $((NUMFILES * 3))`; do
81 cp /etc/termcap $f || exit 10
84 #Create some more files
85 for d in `seq -f d%g $((NUMDIRS * 2 + 1)) $((NUMDIRS * 2 + 3))`; do
86 echo "creating files in $DIR/$d"
87 for e in `seq -f d%g $NUMDIRS`; do
89 for f in `seq -f test%g $NUMDIRS`; do
90 cp /etc/hosts $DIR/$d/$e/$f ||exit 15
95 # these should NOT be taken as duplicates
96 for f in `seq -f $DIR/$d/linkfile.%g $NUMFILES`; do
97 echo "linking files in $DIR/$d"
102 # Get objids for a file on the OST
103 OST_FILES=`seq -f $DIR/testfile.%g $NUMFILES`
104 OST_REMOVE=`$GETSTRIPE $OST_FILES | awk '$1 == 0 { print $2 }' | head -n $NUMFILES`
107 for f in `seq -f testfile.%g $((NUMFILES + 1)) $((NUMFILES * 2))`; do
109 echo "DUPLICATING MDS file $TEST_FILE"
110 $GETSTRIPE -v $TEST_FILE >> $LOG || exit 20
111 MDS_DUPE="$MDS_DUPE $TEST_FILE"
113 MDS_DUPE=`echo $MDS_DUPE | sed "s#$MOUNT/##g"`
116 for f in `seq -f testfile.%g $((NUMFILES * 2 + 1)) $((NUMFILES * 3))`; do
118 echo "REMOVING MDS file $TEST_FILE which has info:"
119 $GETSTRIPE -v $TEST_FILE >> $LOG || exit 30
120 MDS_REMOVE="$MDS_REMOVE $TEST_FILE"
122 MDS_REMOVE=`echo $MDS_REMOVE | sed "s#$MOUNT/##g"`
124 MDTDEVS=`get_mnt_devs mds`
125 OSTDEVS=`get_mnt_devs obdfilter`
126 OSTCOUNT=`echo $OSTDEVS | wc -w`
127 sh llmountcleanup.sh || exit 40
129 # Remove objects associated with files
130 echo "removing objects: `echo $OST_REMOVE`"
131 DEBUGTMP=`mktemp $TMP/debugfs.XXXXXXXXXX`
132 for i in $OST_REMOVE; do
133 echo "rm O/0/d$((i % 32))/$i" >> $DEBUGTMP
135 $DEBUGFS -w -f $DEBUGTMP `echo $OSTDEVS | cut -d' ' -f 1`
138 [ $RET -ne 0 ] && exit 50
141 [ "$FSTYPE" = "ldiskfs" ] && load_module ../ldiskfs/ldiskfs/ldiskfs
142 mount -t $FSTYPE -o loop $MDSDEV $MOUNT || exit 60
150 #Remove files from mds
151 for f in $MDS_REMOVE; do
152 rm $MOUNT/ROOT/$f || exit 70
155 #Create EAs on files so objects are referenced from different files
156 ATTRTMP=`mktemp $TMP/setfattr.XXXXXXXXXX`
157 cd $MOUNT/ROOT || exit 78
158 for f in $MDS_DUPE; do
159 touch $f.bad || exit 74
160 getfattr -n trusted.lov $f | sed "s#$f#&.bad#" > $ATTRTMP
161 setfattr --restore $ATTRTMP || exit 80
168 MDTDEVS=`get_mnt_devs mds`
169 OSTDEVS=`get_mnt_devs obdfilter`
170 OSTCOUNT=`echo $OSTDEVS | wc -w`
173 # Run e2fsck to get mds and ost info
174 # a return status of 1 indicates e2fsck successfuly fixed problems found
177 echo "$E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV"
178 df > /dev/null # update statfs data on disk
179 $E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV
181 [ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 90 || true
185 for OSTDEV in $OSTDEVS; do
186 df > /dev/null # update statfs data on disk
187 $E2FSCK -d -v -fn --mdsdb $MDSDB --ostdb $OSTDB-$i $OSTDEV
189 [ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 100
190 OSTDB_LIST="$OSTDB_LIST $OSTDB-$i"
195 [ "`mount | grep $MOUNT`" ] || setupall
197 # need to turn off shell error detection to get proper error return
198 # lfsck will return 1 if the filesystem had errors fixed
200 echo "lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT"
201 echo y | lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT
203 [ $RET -eq 0 ] && echo "clean after first check" && exit 0
204 echo "LFSCK TEST 1 - finished with rc=$RET"
205 [ $RET -gt $MAX_ERR ] && exit 110 || true
207 # make sure everything gets to the backing store
211 echo "$E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV"
212 df > /dev/null # update statfs data on disk
213 $E2FSCK -d -v -fn --mdsdb $MDSDB $MDSDEV
215 [ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 123 || true
219 for OSTDEV in $OSTDEVS; do
220 df > /dev/null # update statfs data on disk
221 $E2FSCK -d -v -fn --mdsdb $MDSDB --ostdb $OSTDB-$i $OSTDEV
223 [ $RET -gt $MAX_ERR ] && echo "$E2FSCK returned $RET" && exit 124
224 OSTDB_LIST="$OSTDB_LIST $OSTDB-$i"
229 echo "lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT"
230 lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT
232 echo "LFSCK TEST 2 - finished with rc=$RET"
233 [ $RET -ne 0 ] && exit 125 || true
234 if [ -z "$WAS_MOUNTED" ]; then
235 sh llmountcleanup.sh || exit 120
239 rm -f $MDSDB $OSTDB-* || true