Whamcloud - gitweb
corrected an error made in setepall in test-framework.sh, which affects
[fs/lustre-release.git] / lustre / tests / lfscktest.sh
1 #!/bin/bash
2 #set -vx
3 set -e
4
5 TESTNAME="lfscktest"
6 TMP=${TMP:-/tmp}
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}
12 NUMDIRS=${NUMDIRS:-4}
13 LFIND=${LFIND:-"lfs find"}
14 GETFATTR=${GETFATTR:-getfattr}
15 SETFATTR=${SETFATTR:-setfattr}
16 MAX_ERR=1
17
18 export PATH=$LFSCK_PATH:`dirname $0`:`dirname $0`/../utils:$PATH
19
20 [ -z "`which $GETFATTR`" ] && echo "$0: $GETFATTR not found" && exit 5
21 [ -z "`which $SETFATTR`" ] && echo "$0: $SETFATTR not found" && exit 6
22
23 LUSTRE=${LUSTRE:-`dirname $0`/..}
24 . $LUSTRE/tests/test-framework.sh
25 init_test_env $@
26 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
27
28 WAS_MOUNTED=`mount | grep $MOUNT`
29 [ "$WAS_MOUNTED" ] || $FORMAT && $SETUP
30
31 DIR=${DIR:-$MOUNT/$TESTNAME}
32 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && exit 3
33
34 if [ "$WAS_MOUNTED" ]; then
35         LFSCK_SETUP=no
36         MAX_ERR=4               # max expected error from e2fsck
37 fi
38
39 get_mnt_devs() {
40         DEVS=`cat /proc/fs/lustre/$1/*/mntdev`
41         for DEV in $DEVS; do
42                 case $DEV in
43                 *loop*) losetup $DEV | sed -e "s/.*(//" -e "s/).*//" ;;
44                 *) echo $DEV ;;
45                 esac
46         done
47 }
48
49 if [ "$LFSCK_SETUP" != "no" ]; then
50         #Create test directory 
51         rm -rf $DIR
52         mkdir -p $DIR
53         OSTCOUNT=`$LFIND $MOUNT | grep -c "^[0-9]*: "`
54
55         # Create some files on the filesystem
56         for d in `seq -f d%g $NUMDIRS`; do
57                 echo "creating files in $DIR/$d"
58                 for e in `seq -f d%g $NUMDIRS`; do
59                         mkdir -p  $DIR/$d/$e
60                         for f in `seq -f test%g $NUMDIRS`; do
61                                 cp /etc/fstab $DIR/$d/$e/$f ||exit 5
62                         done
63                 done
64         done
65
66         # Create Files to be modified
67         for f in `seq -f $DIR/testfile.%g $((NUMFILES * 3))`; do
68                 echo "creating $f"
69                 cp /etc/termcap $f || exit 10
70         done
71
72         #Create some more files
73         for d in `seq -f d%g $((NUMDIRS * 2 + 1)) $((NUMDIRS * 2 + 3))`; do
74                 echo "creating files in $DIR/$d"
75                 for e in `seq -f d%g $NUMDIRS`; do
76                         mkdir -p  $DIR/$d/$e
77                         for f in `seq -f test%g $NUMDIRS`; do
78                                 cp /etc/hosts $DIR/$d/$e/$f ||exit 15
79                         done
80                 done
81         done
82
83         # these should NOT be taken as duplicates
84         for f in `seq -f $DIR/$d/linkfile.%g $NUMFILES`; do
85                 echo "linking files in $DIR/$d"
86                 cp /etc/hosts $f
87                 ln $f $f.link
88         done
89
90         # Get objids for a file on the OST
91         OST_FILES=`seq -f $DIR/testfile.%g $NUMFILES`
92         OST_REMOVE=`$LFIND $OST_FILES | awk '$1 == 0 { print $2 }' | head -n $NUMFILES`
93
94         export MDS_DUPE=""
95         for f in `seq -f testfile.%g $((NUMFILES + 1)) $((NUMFILES * 2))`; do
96                 TEST_FILE=$DIR/$f
97                 echo "DUPLICATING MDS file $TEST_FILE"
98                 $LFIND -v $TEST_FILE >> $LOG || exit 20
99                 MDS_DUPE="$MDS_DUPE $TEST_FILE"
100         done
101         MDS_DUPE=`echo $MDS_DUPE | sed "s#$MOUNT/##g"`
102
103         export MDS_REMOVE=""
104         for f in `seq -f testfile.%g $((NUMFILES * 2 + 1)) $((NUMFILES * 3))`; do
105                 TEST_FILE=$DIR/$f
106                 echo "REMOVING MDS file $TEST_FILE which has info:"
107                 $LFIND -v $TEST_FILE >> $LOG || exit 30
108                 MDS_REMOVE="$MDS_REMOVE $TEST_FILE"
109         done
110         MDS_REMOVE=`echo $MDS_REMOVE | sed "s#$MOUNT/##g"`
111
112         MDTDEVS=`get_mnt_devs mds`
113         OSTDEVS=`get_mnt_devs obdfilter`
114         OSTCOUNT=`echo $OSTDEVS | wc -w`
115         sh llmountcleanup.sh || exit 40
116
117         # Remove objects associated with files
118         echo "removing objects: `echo $OST_REMOVE`"
119         DEBUGTMP=`mktemp $TMP/debugfs.XXXXXXXXXX`
120         for i in $OST_REMOVE; do
121                 echo "rm O/0/d$((i % 32))/$i" >> $DEBUGTMP
122         done
123         debugfs -w -f $DEBUGTMP `echo $OSTDEVS | cut -d' ' -f 1`
124         RET=$?
125         rm $DEBUGTMP
126         [ $RET -ne 0 ] && exit 50
127
128         SAVE_PWD=$PWD
129         mount -t $FSTYPE -o loop $MDSDEV $MOUNT || exit 60
130         do_umount() {
131                 trap 0
132                 cd $SAVE_PWD
133                 umount -f $MOUNT
134         }
135         trap do_umount EXIT
136
137         #Remove files from mds
138         for f in $MDS_REMOVE; do
139                 rm $MOUNT/ROOT/$f || exit 70
140         done
141
142         #Create EAs on files so objects are referenced from different files
143         ATTRTMP=`mktemp $TMP/setfattr.XXXXXXXXXX`
144         cd $MOUNT/ROOT || exit 78
145         for f in $MDS_DUPE; do
146                 touch $f.bad || exit 74
147                 getfattr -n trusted.lov $f | sed "s#$f#&.bad#" > $ATTRTMP
148                 setfattr --restore $ATTRTMP || exit 80
149         done
150         cd $SAVE_PWD
151         rm $ATTRTMP
152
153         do_umount
154 else
155         MDTDEVS=`get_mnt_devs mds`
156         OSTDEVS=`get_mnt_devs obdfilter`
157         OSTCOUNT=`echo $OSTDEVS | wc -w`
158 fi # LFSCK_SETUP
159
160 # Run e2fsck to get mds and ost info
161 # a return status of 1 indicates e2fsck successfuly fixed problems found
162 set +e
163
164 echo "e2fsck -d -v -fn --mdsdb $MDSDB $MDSDEV"
165 e2fsck -d -v -fn --mdsdb $MDSDB $MDSDEV
166 RET=$?
167 [ $RET -gt $MAX_ERR ] && echo "e2fsck returned $RET" && exit 90 || true
168
169 export OSTDB_LIST=""
170 i=0
171 for OSTDEV in $OSTDEVS; do
172         e2fsck -d -v -fn --mdsdb $MDSDB --ostdb $OSTDB-$i $OSTDEV
173         RET=$?
174         [ $RET -gt $MAX_ERR ] && echo "e2fsck returned $RET" && exit 100
175         OSTDB_LIST="$OSTDB_LIST $OSTDB-$i"
176         i=$((i + 1))
177 done
178
179 #Remount filesystem
180 [ "`mount | grep $MOUNT`" ] || $SETUP
181
182 # need to turn off shell error detection to get proper error return
183 # lfsck will return 1 if the filesystem had errors fixed
184 echo "LFSCK TEST 1"
185 echo "lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT"
186 lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT
187 RET=$?
188 [ $RET -eq 0 ] && echo "clean after first check" && exit 0
189 echo "LFSCK TEST 1 - finished with rc=$RET"
190 [ $RET -gt $MAX_ERR ] && exit 110 || true
191
192 # make sure everything gets to the backing store
193 sync; sleep 2; sync
194
195 echo "LFSCK TEST 2"
196 echo "e2fsck -d -v -fn --mdsdb $MDSDB $MDSDEV"
197 e2fsck -d -v -fn --mdsdb $MDSDB $MDSDEV
198 RET=$?
199 [ $RET -gt $MAX_ERR ] && echo "e2fsck returned $RET" && exit 123 || true
200
201 i=0
202 export OSTDB_LIST=""
203 for OSTDEV in $OSTDEVS; do
204         e2fsck -d -v -fn --mdsdb $MDSDB --ostdb $OSTDB-$i $OSTDEV
205         RET=$?
206         [ $RET -gt $MAX_ERR ] && echo "e2fsck returned $RET" && exit 124
207         OSTDB_LIST="$OSTDB_LIST $OSTDB-$i"
208         i=$((i + 1))
209 done
210
211 echo "LFSCK TEST 2"
212 echo "lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT"
213 lfsck -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT
214 RET=$?
215 echo "LFSCK TEST 2 - finished with rc=$RET"
216 [ $RET -ne 0 ] && exit 125 || true
217 if [ -z "$WAS_MOUNTED" ]; then
218         sh llmountcleanup.sh || exit 120
219 fi
220
221 #Cleanup 
222 rm -f $MDSDB $OSTDB-* || true
223
224 echo "$0: completed"