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