Whamcloud - gitweb
b=4834
[fs/lustre-release.git] / lustre / tests / sanityN.sh
1 #!/bin/bash
2
3 set -e
4
5 ONLY=${ONLY:-"$*"}
6 # bug number for skipped test: 1768 3192 3192
7 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"4   14b  14c"}
8 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
9
10 [ "$ALWAYS_EXCEPT$EXCEPT" ] && echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT"
11
12 SRCDIR=`dirname $0`
13 PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$PATH
14
15 SIZE=${SIZE:-40960}
16 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
17 CREATETEST=${CREATETEST:-createtest}
18 LFIND=${LFIND:-lfind}
19 LSTRIPE=${LSTRIPE:-lstripe}
20 LCTL=${LCTL:-lctl}
21 MCREATE=${MCREATE:-mcreate}
22 OPENFILE=${OPENFILE:-openfile}
23 OPENUNLINK=${OPENUNLINK:-openunlink}
24 TOEXCL=${TOEXCL:-toexcl}
25 TRUNCATE=${TRUNCATE:-truncate}
26 export TMP=${TMP:-/tmp}
27
28 if [ $UID -ne 0 ]; then
29         RUNAS_ID="$UID"
30         RUNAS=""
31 else
32         RUNAS_ID=${RUNAS_ID:-500}
33         RUNAS=${RUNAS:-"runas -u $RUNAS_ID"}
34 fi
35
36 SAVE_PWD=$PWD
37
38 clean() {
39         echo -n "cln.."
40         sh llmountcleanup.sh ${FORCE} > /dev/null || exit 20
41 }
42 CLEAN=${CLEAN:-}
43
44 start() {
45         echo -n "mnt.."
46         sh llrmount.sh > /dev/null || exit 10
47         echo "done"
48 }
49 START=${START:-}
50
51 log() {
52         echo "$*"
53         lctl mark "$*" 2> /dev/null || true
54 }
55
56 trace() {
57         log "STARTING: $*"
58         strace -o $TMP/$1.strace -ttt $*
59         RC=$?
60         log "FINISHED: $*: rc $RC"
61         return 1
62 }
63 TRACE=${TRACE:-""}
64
65 run_one() {
66         if ! mount | grep -q $DIR1; then
67                 $START
68         fi
69         BEFORE=`date +%s`
70         log "== test $1: $2= `date +%H:%M:%S` ($BEFORE)"
71         export TESTNAME=test_$1
72         test_$1 || error "test_$1: exit with rc=$?"
73         unset TESTNAME
74         pass "($((`date +%s` - $BEFORE))s)"
75         cd $SAVE_PWD
76         $CLEAN
77 }
78
79 run_test() {
80         for O in $ONLY; do
81                 if [ "`echo $1 | grep '\<'$O'[a-z]*\>'`" ]; then
82                         echo ""
83                         run_one $1 "$2"
84                         return $?
85                 else
86                         echo -n "."
87                 fi
88         done
89         for X in $EXCEPT $ALWAYS_EXCEPT; do
90                 if [ "`echo $1 | grep '\<'$X'[a-z]*\>'`" ]; then
91                         echo "skipping excluded test $1"
92                         return 0
93                 fi
94         done
95         if [ -z "$ONLY" ]; then
96                 run_one $1 "$2"
97                 return $?
98         fi
99 }
100
101 [ "$SANITYLOG" ] && rm -f $SANITYLOG || true
102
103 error () {
104         log "FAIL: $TESTNAME $@"
105         if [ "$SANITYLOG" ]; then
106                 echo "FAIL: $TESTNAME $@" >> $SANITYLOG
107         else
108                 exit 1
109         fi
110 }
111
112 pass() {
113         echo PASS $@
114 }
115
116 export MOUNT1=`mount| awk '/ lustre/ { print $3 }'| head -n 1`
117 export MOUNT2=`mount| awk '/ lustre/ { print $3 }'| tail -n 1`
118 [ -z "$MOUNT1" ] && error "NAME=$NAME not mounted once"
119 [ "$MOUNT1" = "$MOUNT2" ] && error "NAME=$NAME not mounted twice"
120 [ `mount| awk '/ lustre/ { print $3 }'| wc -l` -ne 2 ] && \
121         error "NAME=$NAME mounted more than twice"
122
123 export DIR1=${DIR1:-$MOUNT1}
124 export DIR2=${DIR2:-$MOUNT2}
125 [ -z "`echo $DIR1 | grep $MOUNT1`" ] && echo "$DIR1 not in $MOUNT1" && exit 96
126 [ -z "`echo $DIR2 | grep $MOUNT2`" ] && echo "$DIR2 not in $MOUNT2" && exit 95
127
128 rm -rf $DIR1/[df][0-9]* $DIR1/lnk
129
130 test_1a() {
131         touch $DIR1/f1
132         [ -f $DIR2/f1 ] || error
133 }
134 run_test 1a "check create on 2 mtpt's =========================="
135
136 test_1b() {
137         chmod 777 $DIR2/f1
138         $CHECKSTAT -t file -p 0777 $DIR1/f1 || error
139         chmod a-x $DIR2/f1
140 }
141 run_test 1b "check attribute updates on 2 mtpt's ==============="
142
143 test_1c() {
144         $CHECKSTAT -t file -p 0666 $DIR1/f1 || error
145 }
146 run_test 1c "check after remount attribute updates on 2 mtpt's ="
147
148 test_1d() {
149         rm $DIR2/f1
150         $CHECKSTAT -a $DIR1/f1 || error
151 }
152 run_test 1d "unlink on one mountpoint removes file on other ===="
153
154 test_2a() {
155         touch $DIR1/f2a
156         ls -l $DIR2/f2a
157         chmod 777 $DIR2/f2a
158         $CHECKSTAT -t file -p 0777 $DIR1/f2a || error
159 }
160 run_test 2a "check cached attribute updates on 2 mtpt's ========"
161
162 test_2b() {
163         touch $DIR1/f2b
164         ls -l $DIR2/f2b
165         chmod 777 $DIR1/f2b
166         $CHECKSTAT -t file -p 0777 $DIR2/f2b || error
167 }
168 run_test 2b "check cached attribute updates on 2 mtpt's ========"
169
170 # NEED TO SAVE ROOT DIR MODE
171 test_2c() {
172         chmod 777 $DIR1
173         $CHECKSTAT -t dir -p 0777 $DIR2 || error
174 }
175 run_test 2c "check cached attribute updates on 2 mtpt's root ==="
176
177 test_2d() {
178         chmod 755 $DIR1
179         $CHECKSTAT -t dir -p 0755 $DIR2 || error
180 }
181 run_test 2d "check cached attribute updates on 2 mtpt's root ==="
182
183 test_3() {
184         ( cd $DIR1 ; ln -s this/is/good lnk )
185         [ "this/is/good" = "`perl -e 'print readlink("'$DIR2/lnk'");'`" ] || \
186                 error
187 }
188 run_test 3 "symlink on one mtpt, readlink on another ==========="
189
190 test_4() {
191         multifstat $DIR1/f4 $DIR2/f4
192 }
193 run_test 4 "fstat validation on multiple mount points =========="
194
195 test_5() {
196         mcreate $DIR1/f5
197         truncate $DIR2/f5 100
198         $CHECKSTAT -t file -s 100 $DIR1/f5 || error
199         rm $DIR1/f5
200 }
201 run_test 5 "create a file on one mount, truncate it on the other"
202
203 test_6() {
204         openunlink $DIR1/f6 $DIR2/f6 || error
205 }
206 run_test 6 "remove of open file on other node =================="
207
208 test_7() {
209         opendirunlink $DIR1/d7 $DIR2/d7 || error
210 }
211 run_test 7 "remove of open directory on other node ============="
212
213 test_8() {
214         opendevunlink $DIR1/dev8 $DIR2/dev8 || error
215 }
216 run_test 8 "remove of open special file on other node =========="
217
218 test_9() {
219         MTPT=1
220         > $DIR2/f9
221         for C in a b c d e f g h i j k l; do
222                 DIR=`eval echo \\$DIR$MTPT`
223                 echo -n $C >> $DIR/f9
224                 [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1
225         done
226         [ "`cat $DIR1/f9`" = "abcdefghijkl" ] || \
227                 error "`od -a $DIR1/f9` != abcdefghijkl"
228 }
229 run_test 9 "append of file with sub-page size on multiple mounts"
230
231 test_10a() {
232         MTPT=1
233         OFFSET=0
234         > $DIR2/f10
235         for C in a b c d e f g h i j k l; do
236                 DIR=`eval echo \\$DIR$MTPT`
237                 echo -n $C | dd of=$DIR/f10 bs=1 seek=$OFFSET count=1
238                 [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1
239                 OFFSET=`expr $OFFSET + 1`
240         done
241         [ "`cat $DIR1/f10`" = "abcdefghijkl" ] || \
242                 error "`od -a $DIR1/f10` != abcdefghijkl"
243 }
244 run_test 10a "write of file with sub-page size on multiple mounts "
245
246 test_10b() {
247         yes "R" | dd of=$DIR1/f10b bs=3k count=1 || error "dd $DIR1"
248
249         truncate $DIR1/f10b 4096 || error "truncate 4096"
250
251         dd if=$DIR2/f10b of=$TMP/f10b-lustre bs=4k count=1 || error "dd $DIR2"
252
253         # create a test file locally to compare
254         yes "R" | dd of=$TMP/f10b bs=3k count=1 || error "dd random"
255         truncate $TMP/f10b 4096 || error "truncate 4096"
256         cmp $TMP/f10b $TMP/f10b-lustre || error "file miscompare"
257 }
258 run_test 10b "write of file with sub-page size on multiple mounts "
259
260 test_11() {
261         mkdir $DIR1/d11
262         multiop $DIR1/d11/f O_c &
263         MULTIPID=$!
264         usleep 200
265         cp -p /bin/ls $DIR1/d11/f
266         $DIR2/d11/f
267         RC=$?
268         kill -USR1 $MULTIPID
269         wait $MULTIPID || error
270         [ $RC -eq 0 ] && error || true
271 }
272 run_test 11 "execution of file opened for write should return error ===="
273
274 test_12() {
275        sh lockorder.sh
276 }
277 run_test 12 "test lock ordering (link, stat, unlink) ==========="
278
279 test_13() {     # bug 2451 - directory coherency
280        rm -rf $DIR1/d13
281        mkdir $DIR1/d13 || error
282        cd $DIR1/d13 || error
283        ls
284        ( touch $DIR1/d13/f13 ) # needs to be a separate shell
285        ls
286        rm -f $DIR2/d13/f13 || error
287        ls 2>&1 | grep f13 && error "f13 shouldn't return an error (1)" || true
288        # need to run it twice
289        ( touch $DIR1/d13/f13 ) # needs to be a separate shell
290        ls
291        rm -f $DIR2/d13/f13 || error
292        ls 2>&1 | grep f13 && error "f13 shouldn't return an error (2)" || true
293 }
294 run_test 13 "test directory page revocation ===================="
295
296 test_14() {
297         mkdir $DIR1/d14
298         cp -p /bin/ls $DIR1/d14/ls
299         exec 100>> $DIR1/d14/ls
300         $DIR2/d14/ls && error || true
301         exec 100<&-
302 }
303 run_test 14 "execution of file open for write returns -ETXTBSY ="
304
305 test_14a() {
306         mkdir -p $DIR1/d14
307         cp -p `which multiop` $DIR1/d14/multiop || error "cp failed"
308         $DIR1/d14/multiop $TMP/test14.junk O_c &
309         MULTIPID=$!
310         sleep 1
311         multiop $DIR2/d14/multiop Oc && error "expected error, got success"
312         kill -USR1 $MULTIPID || return 2
313         wait $MULTIPID || return 3
314 }
315 run_test 14a "open(RDWR) of executing file returns -ETXTBSY ===="
316
317 test_14b() { # bug 3192
318         mkdir -p $DIR1/d14
319         cp -p `which multiop` $DIR1/d14/multiop || error "cp failed"
320         $DIR1/d14/multiop $TMP/test14.junk O_c &
321         MULTIPID=$!
322         sleep 1
323         truncate $DIR2/d14/multiop 0 && error "expected error, got success"
324         kill -USR1 $MULTIPID || return 2
325         wait $MULTIPID || return 3
326 }
327 run_test 14b "truncate of executing file returns -ETXTBSY ======"
328
329 test_14c() { # bug 3430
330         mkdir -p $DIR1/d14
331         cp -p `which multiop` $DIR1/d14/multiop || error "cp failed"
332         $DIR1/d14/multiop $TMP/test14.junk O_c &
333         MULTIPID=$!
334         sleep 1
335         cp /etc/hosts $DIR2/d14/multiop && error "expected error, got success"
336         kill -USR1 $MULTIPID || return 2
337         wait $MULTIPID || return 3
338         #cmp `which multiop` $DIR1/d14/multiop || error "binary changed"
339 }
340 run_test 14c "open(O_TRUNC) of executing file return -ETXTBSY =="
341
342 test_15() {     # bug 974 - ENOSPC
343         echo $PATH
344         sh oos2.sh $MOUNT1 $MOUNT2
345 }
346 run_test 15 "test out-of-space with multiple writers ==========="
347
348 test_16() {
349         fsx -c 50 -p 100 -N 2500 $MOUNT1/fsxfile $MOUNT2/fsxfile
350 }
351 run_test 16 "2500 iterations of dual-mount fsx ================="
352
353 cancel_lru_locks() {
354         for d in /proc/fs/lustre/ldlm/namespaces/$1*; do
355                 echo clear > $d/lru_size
356         done
357         grep "[0-9]" /proc/fs/lustre/ldlm/namespaces/$1*/lock_unused_count /dev/null
358 }
359
360 test_17() { # bug 3513, 3667
361         [ ! -d /proc/fs/lustre/ost ] && echo "skipping OST-only test" && return
362
363         cp /etc/termcap $DIR1/f17
364         cancel_lru_locks OSC > /dev/null
365         #define OBD_FAIL_ONCE|OBD_FAIL_LDLM_CREATE_RESOURCE    0x30a
366         echo 0x8000030a > /proc/sys/lustre/fail_loc
367         ls -ls $DIR1/f17 | awk '{ print $1,$6 }' > $DIR1/f17-1 & \
368         ls -ls $DIR2/f17 | awk '{ print $1,$6 }' > $DIR2/f17-2
369         wait
370         diff -u $DIR1/f17-1 $DIR2/f17-2 || error "files are different"
371 }
372 run_test 17 "resource creation/LVB creation race ==============="
373
374 test_18() {
375         ./mmap_sanity -d $MOUNT1 -m $MOUNT2
376 }
377 run_test 18 "mmap sanity check ================================="
378
379 test_18() {
380         ./mmap_sanity -d $MOUNT1 -m $MOUNT2
381         sync; sleep 1; sync
382 }
383 #run_test 18 "mmap sanity check ================================="
384
385 test_19() { # bug3811
386         [ -d /proc/fs/lustre/obdfilter ] || return 0
387
388         MAX=`cat /proc/fs/lustre/obdfilter/*/readcache_max_filesize | head -n 1`
389         for O in /proc/fs/lustre/obdfilter/OST*; do
390                 echo 4096 > $O/readcache_max_filesize
391         done
392         dd if=/dev/urandom of=$TMP/f19b bs=512k count=32
393         SUM=`cksum $TMP/f19b | cut -d" " -f 1,2`
394         cp $TMP/f19b $DIR1/f19b
395         for i in `seq 1 20`; do
396                 [ $((i % 5)) -eq 0 ] && log "test_18 loop $i"
397                 cancel_lru_locks OSC > /dev/null
398                 cksum $DIR1/f19b | cut -d" " -f 1,2 > $TMP/sum1 & \
399                 cksum $DIR2/f19b | cut -d" " -f 1,2 > $TMP/sum2
400                 wait
401                 [ "`cat $TMP/sum1`" = "$SUM" ] || \
402                         error "$DIR1/f19b `cat $TMP/sum1` != $SUM"
403                 [ "`cat $TMP/sum2`" = "$SUM" ] || \
404                         error "$DIR2/f19b `cat $TMP/sum2` != $SUM"
405         done
406         for O in /proc/fs/lustre/obdfilter/OST*; do
407                 echo $MAX > $O/readcache_max_filesize
408         done
409         rm $DIR1/f19b
410 }
411 #run_test 19 "test concurrent uncached read races ==============="
412
413 test_20() {
414         mkdir $DIR1/d20
415         cancel_lru_locks OSC
416         CNT=$((`cat /proc/fs/lustre/llite/fs0/dump_page_cache | wc -l`))
417         multiop $DIR1/f20 Ow8190c
418         multiop $DIR2/f20 Oz8194w8190c
419         multiop $DIR1/f20 Oz0r8190c
420         cancel_lru_locks OSC
421         CNTD=$((`cat /proc/fs/lustre/llite/fs0/dump_page_cache | wc -l` - $CNT))
422         [ $CNTD -gt 0 ] && \
423             error $CNTD" page left in cache after lock cancel" || true
424 }
425
426 run_test 20 "test extra readahead page left in cache ===="
427
428
429 log "cleanup: ======================================================"
430 rm -rf $DIR1/[df][0-9]* $DIR1/lnk || true
431
432 echo '=========================== finished ==============================='
433 [ -f "$SANITYLOG" ] && cat $SANITYLOG && exit 1 || true