Whamcloud - gitweb
Branch b1_4_mountconf
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # Run test by setting NOSETUP=true when ltest has setup env for us
7 set -e
8
9 SRCDIR=`dirname $0`
10 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
11
12 ONLY=${ONLY:-"$*"}
13 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""}
14 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
15
16 case `uname -r` in
17 2.6*) FSTYPE=${FSTYPE:-ldiskfs};;
18 *) error "unsupported kernel" ;;
19 esac
20
21 [ "$ALWAYS_EXCEPT$EXCEPT" ] && \
22         echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
23
24 TMP=${TMP:-/tmp}
25
26 LFS=${LFS:-lfs}
27 LCTL=${LCTL:-lctl}
28 LSTRIPE=${LSTRIPE:-"$LFS setstripe"}
29 TSTID=${TSTID:-60000}
30 RUNAS=${RUNAS:-"runas -u $TSTID"}
31 TSTUSR=${TSTUSR:-"quota_usr"}
32 BLK_SZ=1024
33 BUNIT_SZ=${BUNIT_SZ:-1000}      # default 1000 quota blocks
34 BTUNE_SZ=${BTUNE_SZ:-500}       # default 50% of BUNIT_SZ
35 IUNIT_SZ=${IUNIT_SZ:-10}        # default 10 files
36 ITUNE_SZ=${ITUNE_SZ:-5}         # default 50% of IUNIT_SZ
37 MAX_DQ_TIME=604800
38 MAX_IQ_TIME=604800
39
40 log() {
41         echo "$*"
42         $LCTL mark "$*" 2> /dev/null || true
43 }
44
45 trace() {
46         log "STARTING: $*"
47         strace -o $TMP/$1.strace -ttt $*
48         RC=$?
49         log "FINISHED: $*: rc $RC"
50         return 1
51 }
52 TRACE=${TRACE:-""}
53
54 run_one() {
55         BEFORE=`date +%s`
56         log "== test $1: $2= `date +%H:%M:%S` ($BEFORE)"
57         export TESTNAME=test_$1
58         test_$1 || error "exit with rc=$?"
59         unset TESTNAME
60         pass "($((`date +%s` - $BEFORE))s)"
61         cd $SAVE_PWD
62 }
63
64 build_test_filter() {
65         for O in $ONLY; do
66             eval ONLY_${O}=true
67         done
68         for E in $EXCEPT $ALWAYS_EXCEPT; do
69             eval EXCEPT_${E}=true
70         done
71         # turn on/off quota tests must be included
72         eval ONLY_0=true
73         eval ONLY_9=true
74 }
75
76 _basetest() {
77         echo $*
78 }
79
80 basetest() {
81         IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
82 }
83
84 run_test() {
85          base=`basetest $1`
86          if [ "$ONLY" ]; then
87                  testname=ONLY_$1
88                  if [ ${!testname}x != x ]; then
89                         run_one $1 "$2"
90                         return $?
91                  fi
92                  testname=ONLY_$base
93                  if [ ${!testname}x != x ]; then
94                          run_one $1 "$2"
95                          return $?
96                  fi
97                  echo -n "."
98                  return 0
99         fi
100         testname=EXCEPT_$1
101         if [ ${!testname}x != x ]; then
102                  echo "skipping excluded test $1"
103                  return 0
104         fi
105         testname=EXCEPT_$base
106         if [ ${!testname}x != x ]; then
107                  echo "skipping excluded test $1 (base $base)"
108                  return 0
109         fi
110         run_one $1 "$2"
111         return $?
112 }
113
114 [ "$SANITYLOG" ] && rm -f $SANITYLOG || true
115
116 error() { 
117         sysctl -w lustre.fail_loc=0
118         log "FAIL: $TESTNAME $@"
119         if [ "$SANITYLOG" ]; then
120                 echo "FAIL: $TESTNAME $@" >> $SANITYLOG
121         else
122                 exit 1
123         fi
124 }
125
126 pass() { 
127         echo PASS $@
128 }
129
130 mounted_lustre_filesystems() {
131         awk '($3 ~ "lustre" && $1 ~ ":") { print $2 }' /proc/mounts
132 }
133 MOUNT="`mounted_lustre_filesystems`"
134 if [ -z "$MOUNT" ]; then
135         export QUOTA_OPTS="quotaon=ug"
136         sh llmount.sh
137         MOUNT="`mounted_lustre_filesystems`"
138         [ -z "$MOUNT" ] && error "NAME=$NAME not mounted"
139         I_MOUNTED=yes
140 fi
141
142 [ `echo $MOUNT | wc -w` -gt 1 ] && error "NAME=$NAME mounted more than once"
143
144 DIR=${DIR:-$MOUNT}
145 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && exit 99
146
147 LPROC=/proc/fs/lustre
148 LOVNAME=`cat $LPROC/llite/*/lov/common_name | tail -n 1`
149 OSTCOUNT=`cat $LPROC/lov/$LOVNAME/numobd`
150 STRIPECOUNT=`cat $LPROC/lov/$LOVNAME/stripecount`
151 STRIPESIZE=`cat $LPROC/lov/$LOVNAME/stripesize`
152 ORIGFREE=`cat $LPROC/lov/$LOVNAME/kbytesavail`
153 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
154 MDS=$(\ls $LPROC/mds 2> /dev/null | grep -v num_refs | tail -n 1)
155 TSTDIR="$MOUNT/quota_dir"
156
157 build_test_filter
158
159
160 # set_blk_tunables(btune_sz)
161 set_blk_tunesz() {
162         # set btune size on all obdfilters
163         for i in `ls /proc/fs/lustre/obdfilter/*/quota_btune_sz`; do
164                 echo $(($1 * $BLK_SZ)) > $i
165         done
166         # set btune size on mds
167         for i in `ls /proc/fs/lustre/mds/mds*/quota_btune_sz`; do
168                 echo $(($1 * $BLK_SZ)) > $i
169         done
170 }
171 # se_blk_unitsz(bunit_sz)
172 set_blk_unitsz() {
173         for i in `ls /proc/fs/lustre/obdfilter/*/quota_bunit_sz`; do
174                 echo $(($1 * $BLK_SZ)) > $i
175         done
176         for i in `ls /proc/fs/lustre/mds/mds*/quota_bunit_sz`; do
177                 echo $(($1 * $BLK_SZ)) > $i
178         done
179 }
180 # set_file_tunesz(itune_sz)
181 set_file_tunesz() {
182         # set iunit and itune size on all obdfilters
183         for i in `ls /proc/fs/lustre/obdfilter/*/quota_itune_sz`; do
184                 echo $1 > $i
185         done
186         # set iunit and itune size on mds
187         for i in `ls /proc/fs/lustre/mds/mds*/quota_itune_sz`; do
188                 echo $1 > $i
189         done
190
191
192 }
193 # set_file_unitsz(iunit_sz)
194 set_file_unitsz() {
195         for i in `ls /proc/fs/lustre/obdfilter/*/quota_iunit_sz`; do
196                 echo $1 > $i
197         done;
198         for i in `ls /proc/fs/lustre/mds/mds*/quota_iunit_sz`; do
199                 echo $1 > $i
200         done
201 }
202
203 # These are for test on local machine,if run sanity-quota.sh on 
204 # real cluster, ltest should have setup the test environment: 
205 #
206 # - create test user/group on all servers with same id.
207 # - set unit size/tune on all servers size to reasonable value.
208 pre_test() {
209         if [ -z "$NOSETUP" ]; then
210                 # set block tunables
211                 set_blk_tunesz $BTUNE_SZ
212                 set_blk_unitsz $BUNIT_SZ
213                 # set file tunaables
214                 set_file_tunesz $ITUNE_SZ
215                 set_file_unitsz $IUNIT_SZ
216         fi
217 }
218 pre_test
219
220 post_test() {
221         if [ -z "$NOSETUP" ]; then
222                 # restore block tunables to default size
223                 set_blk_unitsz $((1024 * 100))
224                 set_blk_tunesz $((1024 * 50))
225                 # restore file tunables to default size
226                 set_file_unitsz 5000
227                 set_file_tunesz 2500
228         fi
229 }
230
231 setup() {
232         # create local test group
233         GRP="`cat /etc/group | grep "$TSTUSR" | awk -F: '{print $1}'`"
234         if [ -z "$GRP" ]; then
235                 groupadd -g $TSTID "$TSTUSR"
236         fi
237         TSTID="`cat /etc/group | grep "$TSTUSR" | awk -F: '{print $3}'`"
238
239         # create test user
240         USR="`cat /etc/passwd | grep "$TSTUSR" | awk -F: '{print $1}'`"
241         if [ -z "$USR" ]; then
242                 useradd -u $TSTID -g $TSTID -d /tmp "$TSTUSR"
243         fi
244         
245         RUNAS="runas -u $TSTID"
246         
247         # create test directory
248         [ -d $TSTDIR ] || mkdir $TSTDIR 
249         chmod 777 $TSTDIR
250 }
251 setup
252
253 # set quota
254 test_0() {
255         $LFS quotaoff -ug $MOUNT
256         $LFS quotacheck -ug $MOUNT
257
258         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
259         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
260 }
261 run_test 0 "Set quota ============================="
262
263 # block hard limit (normal use and out of quota)
264 test_1() {
265         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
266         TESTFILE="$TSTDIR/quota_tst10"
267         
268         echo "  User quota (limit: $LIMIT bytes)"
269         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $MOUNT
270         
271         $LFS setstripe $TESTFILE 65536 0 1
272         chown $TSTUSR.$TSTUSR $TESTFILE
273
274         echo "    Write ..."
275         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) > /dev/null 2>&1 || error "(usr) write failure, but expect success"
276         echo "    Done"
277         echo "    Write out of block quota ..."
278         # this time maybe cache write,  ignore it's failure
279         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) seek=$(($LIMIT/2)) > /dev/null 2>&1 || echo " " > /dev/null
280         # flush cache, ensure noquota flag is setted on client
281         sync; sleep 1; sync;
282         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$LIMIT > /dev/null 2>&1 && error "(usr) write success, but expect EDQUOT"
283         echo "    EDQUOT"
284
285         rm -f $TESTFILE
286         
287         echo "  Group quota (limit: $LIMIT bytes)"
288         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT         # clear user limit
289         $LFS setquota -g $TSTUSR 0 $LIMIT 0 0 $MOUNT
290         TESTFILE="$TSTDIR/quota_tst11"
291
292         $LFS setstripe $TESTFILE 65536 0 1
293         chown $TSTUSR.$TSTUSR $TESTFILE
294
295         echo "    Write ..."
296         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) > /dev/null 2>&1 || error "(grp) write failure, but expect success"
297         echo "    Done"
298         echo "    Write out of block quota ..."
299         # this time maybe cache write, ignore it's failure
300         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) seek=$(($LIMIT/2)) > /dev/null 2>&1 || echo " " > /dev/null
301         sync; sleep 1; sync;
302         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$LIMIT > /dev/null 2>&1 && error "(grp) write success, but expect EDQUOT"
303         echo "    EDQUOT"
304
305         # cleanup
306         rm -f $TESTFILE
307         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
308 }
309 run_test 1 "Block hard limit (normal use and out of quota) ==="
310
311 # file hard limit (normal use and out of quota)
312 test_2() {
313         LIMIT=$(($IUNIT_SZ * 10)) # 10 iunits on mds
314         TESTFILE="$TSTDIR/quota_tstr20"
315
316         echo "  User quota (limit: $LIMIT files)"
317         $LFS setquota -u $TSTUSR 0 0 0 $LIMIT $MOUNT
318
319         echo "    Create $LIMIT files ..."
320         for i in `seq ${LIMIT}`; do
321                 $RUNAS touch ${TESTFILE}_$i > /dev/null 2>&1 || error "(usr) touch failure, but except success"
322         done
323         echo "    Done"
324         echo "    Create out of file quota ..."
325         $RUNAS touch ${TESTFILE}_xxx > /dev/null 2>&1 && error "(usr) touch success, but expect EDQUOT"
326         echo "    EDQUOT"
327
328         for i in `seq ${LIMIT}`; do
329                 rm -f ${TESTFILE}_$i
330         done
331
332         echo "  Group quota (limit: $LIMIT files)"
333         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT         # clear user limit
334         $LFS setquota -g $TSTUSR 0 0 0 $LIMIT $MOUNT
335         TESTFILE="$TSTDIR/quota_tst21"
336
337         echo "    Create $LIMIT files ..."
338         for i in `seq ${LIMIT}`; do
339                 $RUNAS touch ${TESTFILE}_$i > /dev/null 2>&1 || error "(grp) touch failure, but expect success"
340         done
341         echo "    Done"
342         echo "    Create out of file quota ..."
343         $RUNAS touch ${TESTFILE}_xxx > /dev/null 2>&1 && error "(grp) touch success, but expect EDQUOT"
344         echo "    EDQUOT"
345
346         # cleanup
347         for i in `seq ${LIMIT}`; do
348                 rm -f ${TESTFILE}_$i
349         done
350         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
351 }
352 run_test 2 "File hard limit (normal use and out of quota) ==="
353
354 test_block_soft() {
355         TESTFILE=$1
356         GRACE=$2
357
358         echo "    Write to exceed soft limit"
359         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ >/dev/null 2>&1 || error "write failure, but expect success"
360         sync; sleep 1; sync;
361
362         echo "    Write before timer goes off"
363         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$BUNIT_SZ >/dev/null 2>&1 || error "write failure, but expect success"
364         sync; sleep 1; sync;
365         echo "    Done"
366         
367         echo "    Sleep $GRACE seconds ..."
368         sleep $GRACE
369
370         echo "    Write after timer goes off"
371         # maybe cache write, ignore.
372         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$(($BUNIT_SZ * 2)) >/dev/null 2>&1 || echo " " > /dev/null
373         sync; sleep 1; sync;
374         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=1 seek=$(($BUNIT_SZ * 3)) >/dev/null 2>&1 && error "write success, but expect EDQUOT"
375         echo "    EDQUOT"
376
377         echo "    Unlink file to stop timer"
378         rm -f $TESTFILE
379         echo "    Done"
380
381         echo "    Write ..."
382         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ >/dev/null 2>&1 || error "write failure, but expect success"
383         echo "    Done"
384
385         # cleanup
386         rm -f $TESTFILE
387 }
388
389 # block soft limit (start timer, timer goes off, stop timer)
390 test_3() {
391         LIMIT=$(( $BUNIT_SZ * 2 )) # 1 bunit on mds and 1 bunit on the ost
392         GRACE=10
393
394         echo "  User quota (soft limit: $LIMIT bytes  grace: $GRACE seconds)"
395         TESTFILE="$TSTDIR/quota_tst30"
396         $LFS setstripe $TESTFILE 65536 0 1
397         chown $TSTUSR.$TSTUSR $TESTFILE
398
399         $LFS setquota -t -u $GRACE $MAX_IQ_TIME $MOUNT
400         $LFS setquota -u $TSTUSR $LIMIT 0 0 0 $MOUNT
401
402         test_block_soft $TESTFILE $GRACE
403         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
404
405         echo "  Group quota (soft limit: $LIMIT bytes  grace: $GRACE seconds)"
406         TESTFILE="$TSTDIR/quota_tst31"
407         $LFS setstripe $TESTFILE 65536 0 1
408         chown $TSTUSR.$TSTUSR $TESTFILE
409
410         $LFS setquota -t -g $GRACE $MAX_IQ_TIME $MOUNT
411         $LFS setquota -g $TSTUSR $LIMIT 0 0 0 $MOUNT
412         TESTFILE="$TSTDIR/quota_tst31"
413
414         test_block_soft $TESTFILE $GRACE
415         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
416 }
417 run_test 3 "Block soft limit (start timer, timer goes off, stop timer) ==="
418
419 test_file_soft() {
420         TESTFILE=$1
421         LIMIT=$2
422         GRACE=$3
423
424         echo "    Create files to exceed soft limit"
425         for i in `seq $LIMIT`; do
426                 $RUNAS touch ${TESTFILE}_$i >/dev/null 2>&1 || error "touch failure, but expect success"
427         done
428         echo "    Done"
429
430         echo "    Create file before timer goes off"
431         $RUNAS touch ${TESTFILE}_before >/dev/null 2>&1 || error "touch before timer goes off failure, but expect success"
432         echo "    Done"
433
434         echo "    Sleep $GRACE seconds ..."
435         sleep $GRACE
436         
437         echo "    Create file after timer goes off"
438         for i in `seq $(($IUNIT_SZ - 1))`; do
439                 $RUNAS touch ${TESTFILE}_after_$i >/dev/null 2>&1 || error "touch ${TESTFILE}_after_$i failure, but expect success"
440         done
441         $RUNAS touch ${TESTFILE}_after >/dev/null 2>&1 && error "touch after timer goes off success, but expect EDQUOT"
442         echo "    EDQUOT"
443
444         echo "    Unlink files to stop timer"
445         for i in `seq $LIMIT`; do
446                 rm -f ${TESTFILE}_$i >/dev/null 2>&1 || error "rm ${TESTFILE}_$i failure"
447         done
448         rm -f ${TESTFILE}_before
449         for i in `seq $(($IUNIT_SZ - 1))`; do
450                 rm -f ${TESTFILE}_after_$i >/dev/null 2>&1 || error "rm ${TESTFILE}_after_$i failure"
451         done
452         echo "    Done"
453
454         echo "    Create file"
455         $RUNAS touch ${TESTFILE}_xxx >/dev/null 2>&1 || error "touch after timer stop failure, but expect success"
456         echo "    Done"
457
458         # cleanup
459         rm -f ${TESTFILE}_xxx
460 }
461
462 # file soft limit (start timer, timer goes off, stop timer)
463 test_4() {
464         LIMIT=$(($IUNIT_SZ * 10))       # 10 iunits on mds
465         TESTFILE="$TSTDIR/quota_tst40"
466         GRACE=5
467
468         echo "  User quota (soft limit: $LIMIT files  grace: $GRACE seconds)"
469         $LFS setquota -t -u $MAX_DQ_TIME $GRACE $MOUNT
470         $LFS setquota -u $TSTUSR 0 0 $LIMIT 0 $MOUNT
471
472         test_file_soft $TESTFILE $LIMIT $GRACE
473         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
474
475         echo "  Group quota (soft limit: $LIMIT files  grace: $GRACE seconds)"
476         $LFS setquota -t -g $MAX_DQ_TIME $GRACE $MOUNT
477         $LFS setquota -g $TSTUSR 0 0 $LIMIT 0 $MOUNT
478         TESTFILE="$TSTDIR/quota_tst41"
479
480         test_file_soft $TESTFILE $LIMIT $GRACE
481         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
482         
483         # cleanup
484         $LFS setquota -t -u $MAX_DQ_TIME $MAX_IQ_TIME $MOUNT
485         $LFS setquota -t -g $MAX_DQ_TIME $MAX_IQ_TIME $MOUNT
486 }
487 run_test 4 "File soft limit (start timer, timer goes off, stop timer) ==="
488
489 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
490 test_5() {
491         BLIMIT=$(( $BUNIT_SZ * $((OSTCOUNT + 1)) * 10)) # 10 bunits on each server
492         ILIMIT=$(( $IUNIT_SZ * 10 )) # 10 iunits on mds
493         
494         echo "  Set quota limit (0 $BLIMIT 0 $ILIMIT) for $TSTUSR.$TSTUSR"
495         $LFS setquota -u $TSTUSR 0 $BLIMIT 0 $ILIMIT $MOUNT
496         $LFS setquota -g $TSTUSR 0 $BLIMIT 0 $ILIMIT $MOUNT
497         
498         echo "  Create more than $ILIMIT files and alloc more than $BLIMIT blocks ..."
499         for i in `seq $(($ILIMIT + 1))`; do
500                 touch $TSTDIR/quota_tst50_$i > /dev/null 2>&1 || error "touch failure, expect success"
501         done
502         dd if=/dev/zero of=$TSTDIR/quota_tst50_1 bs=$BLK_SZ count=$(($BLIMIT+1)) > /dev/null 2>&1 || error "write failure, expect success"
503
504         echo "  Chown files to $TSTUSR.$TSTUSR ..."
505         for i in `seq $(($ILIMIT + 1))`; do
506                 chown $TSTUSR.$TSTUSR $TSTDIR/quota_tst50_$i > /dev/null 2>&1 || error "chown failure, but expect success"
507         done
508
509         # cleanup
510         for i in `seq $(($ILIMIT + 1))`; do
511                 rm -f $TSTDIR/quota_tst50_$i
512         done
513         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
514         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
515 }
516 run_test 5 "Chown & chgrp (chown & chgrp successfully even out of block/file quota) ==="
517
518 # block quota acquire & release
519 test_6() {
520         if [ $OSTCOUNT -lt 2 ]; then
521                 echo "WARN: too few osts, skip this test."
522                 return 0;
523         fi
524
525         LIMIT=$(($BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits per server
526         FILEA="$TSTDIR/quota_tst60_a"
527         FILEB="$TSTDIR/quota_tst60_b"
528         
529         echo "  Set block limit $LIMIT bytes to $TSTUSR.$TSTUSR"
530         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $MOUNT
531         $LFS setquota -g $TSTUSR 0 $LIMIT 0 0 $MOUNT
532
533         echo "  Create filea on OST0 and fileb on OST1"
534         $LFS setstripe $FILEA 65536 0 1
535         $LFS setstripe $FILEB 65536 1 1
536         chown $TSTUSR.$TSTUSR $FILEA
537         chown $TSTUSR.$TSTUSR $FILEB
538
539         echo "  Exceed quota limit ..."
540         $RUNAS dd if=/dev/zero of=$FILEB bs=$BLK_SZ count=$(($LIMIT - $BUNIT_SZ * $OSTCOUNT)) >/dev/null 2>&1 || error "write fileb failure, but expect success"
541         sync; sleep 1; sync;
542         $RUNAS dd if=/dev/zero of=$FILEB bs=$BLK_SZ seek=$LIMIT count=$BUNIT_SZ >/dev/null 2>&1 && error "write fileb success, but expect EDQUOT"
543         sync; sleep 1; sync;
544         echo "  Write to OST0 return EDQUOT"
545         # this write maybe cache write, ignore it's failure
546         $RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ count=$(($BUNIT_SZ * 2)) >/dev/null 2>&1 || echo " " > /dev/null
547         sync; sleep 1; sync;
548         $RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ count=$(($BUNIT_SZ * 2)) seek=$(($BUNIT_SZ *2)) >/dev/null 2>&1 && error "write filea success, but expect EDQUOT"
549         echo "  EDQUOT"
550
551         echo "  Remove fileb to let OST1 release quota"
552         rm -f $FILEB
553
554         echo "  Write to OST0"
555         $RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ count=$(($LIMIT - $BUNIT_SZ * $OSTCOUNT)) >/dev/null 2>&1 || error "write filea failure, expect success"
556         echo "  Done"
557
558         # cleanup
559         rm -f $FILEA
560         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
561         $LFS setquota -g $TSTUSR 0 0 0 0 $MOUNT
562         return 0
563 }
564 run_test 6 "Block quota acquire & release ========="
565
566 # quota recovery (block quota only by now)
567 test_7()
568 {
569         if [ -z "`lsmod|grep mds`" ]; then 
570                 echo "WARN: no local mds, skip this test"
571                 return 0
572         fi
573
574         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
575         TESTFILE="$TSTDIR/quota_tst70"
576         
577         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $MOUNT
578         
579         $LFS setstripe $TESTFILE 65536 0 1
580         chown $TSTUSR.$TSTUSR $TESTFILE
581
582         echo "  Write to OST0..."
583         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ >/dev/null 2>&1 || error "write failure, but expect success"
584         
585         #define OBD_FAIL_OBD_DQACQ               0x604
586         echo 0x604 > /proc/sys/lustre/fail_loc
587         echo "  Remove files on OST0"
588         rm -f $TESTFILE
589         echo 0 > /proc/sys/lustre/fail_loc
590
591         echo "  Trigger recovery..."
592         OSC0_UUID="`$LCTL dl | awk '/.* *-osc-* / { print $1 }'`"
593         for i in $OSC0_UUID; do
594                 $LCTL --device $i activate > /dev/null 2>&1 || error "activate osc failed!"
595         done
596
597         # sleep a while to wait for recovery done
598         sleep 20
599
600         # check limits
601         PATTERN="`echo $MOUNT | sed 's/\//\\\\\//g'`"
602         TOTAL_LIMIT="`$LFS quota -u $TSTUSR $MOUNT | awk '/^.*'$PATTERN'.*[[:digit:]+][[:space:]+]/ { print $4 }'`"
603         [ $TOTAL_LIMIT -eq $LIMIT ] || error "total limits not recovery!"
604         echo "  total limits = $TOTAL_LIMIT"
605         
606         OST0_UUID=`$LCTL dl | awk '/.*OST_[^ ]+_UUID.* / { print $5 }'`
607         [ -z "$OST0_UUID" ] && OST0_UUID=`$LCTL dl | awk '/.*ost1_[^ ]*UUID.* / { print $5 }'`
608         OST0_LIMIT="`$LFS quota -o $OST0_UUID -u $TSTUSR $MOUNT | awk '/^.*[[:digit:]+][[:space:]+]/ { print $3 }'`"
609         [ $OST0_LIMIT -eq $BUNIT_SZ ] || error "high limits not released!"
610         echo "  limits on $OST0_UUID = $OST0_LIMIT"
611
612         # cleanup
613         $LFS setquota -u $TSTUSR 0 0 0 0 $MOUNT
614 }
615 run_test 7 "Quota recovery (only block limit) ======"
616
617 # run dbench with quota enabled
618 test_8() {
619         BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
620         FILE_LIMIT=1000000
621         DBENCH_LIB=${DBENCH_LIB:-/usr/lib/dbench}
622         
623         [ ! -d $DBENCH_LIB ] && echo "dbench not installed, skip this test" && return 0
624         
625         echo "  Set enough high limit for user: $TSTUSR"
626         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
627         echo "  Set enough high limit for group: $TSTUSR"
628         $LFS setquota -g $USER 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
629         
630
631         TGT=$TSTDIR/client.txt
632         SRC=${SRC:-$DBENCH_LIB/client.txt}
633         [ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT
634         SRC=$DBENCH_LIB/client_plain.txt
635         [ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT
636
637         SAVE_PWD=$PWD
638         cd $TSTDIR
639         $RUNAS dbench -c client.txt 3
640         RC=$?
641         
642         cd $SAVE_PWD
643         return $RC
644 }
645 run_test 8 "Run dbench with quota enabled ==========="
646
647 # turn off quota
648 test_9()
649 {
650         $LFS quotaoff $MOUNT
651         return 0
652 }
653 run_test 9 "Quota off ==============================="
654
655
656 log "cleanup: ======================================================"
657 if [ "`mount | grep ^$NAME`" ]; then
658         rm -fr $TSTDIR
659         post_test
660         # delete test user and group
661         userdel "$TSTUSR"
662         if [ "$I_MOUNTED" = "yes" ]; then
663                 sh llmountcleanup.sh || error "llmountcleanup failed"
664         fi
665 fi
666
667 echo '=========================== finished ==============================='
668 [ -f "$SANITYLOG" ] && cat $SANITYLOG && exit 1 || true
669