Whamcloud - gitweb
Branch HEAD
[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 #kernel 2.4.x doesn't support quota
10 K_VER=`uname --kernel-release | cut -b 1-3`
11 if [ $K_VER = "2.4" ]; then
12     echo "Kernel 2.4 doesn't support quota"
13     exit 0
14 fi
15
16 SRCDIR=`dirname $0`
17 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
18
19 ONLY=${ONLY:-"$*"}
20 ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT"
21 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
22
23 case `uname -r` in
24 2.6*) FSTYPE=${FSTYPE:-ldiskfs};;
25 *) error "unsupported kernel" ;;
26 esac
27
28 [ "$ALWAYS_EXCEPT$EXCEPT" ] && \
29         echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
30
31 TMP=${TMP:-/tmp}
32
33 ORIG_PWD=${PWD}
34 TSTID=${TSTID:-60000}
35 TSTID2=${TSTID2:-60001}
36 TSTUSR=${TSTUSR:-"quota_usr"}
37 TSTUSR2=${TSTUSR2:-"quota_2usr"}
38 BLK_SZ=1024
39 BUNIT_SZ=${BUNIT_SZ:-1000}      # default 1000 quota blocks
40 BTUNE_SZ=${BTUNE_SZ:-500}       # default 50% of BUNIT_SZ
41 IUNIT_SZ=${IUNIT_SZ:-10}        # default 10 files
42 ITUNE_SZ=${ITUNE_SZ:-5}         # default 50% of IUNIT_SZ
43 MAX_DQ_TIME=604800
44 MAX_IQ_TIME=604800
45
46 TRACE=${TRACE:-""}
47 LUSTRE=${LUSTRE:-`dirname $0`/..}
48 . $LUSTRE/tests/test-framework.sh
49 init_test_env $@
50 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
51
52 [ "$SLOW" = "no" ] && EXCEPT_SLOW="9 10 11"
53
54 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
55
56 [ "$QUOTALOG" ] && rm -f $QUOTALOG || true
57
58 DIR=${DIR:-$MOUNT}
59 DIR2=${DIR2:-$MOUNT2}
60
61 cleanup_and_setup_lustre
62
63 LOVNAME=`cat $LPROC/llite/*/lov/common_name | tail -n 1`
64 OSTCOUNT=`cat $LPROC/lov/$LOVNAME/numobd`
65
66 SHOW_QUOTA_USER="$LFS quota -u $TSTUSR $DIR"
67 SHOW_QUOTA_GROUP="$LFS quota -g $TSTUSR $DIR"
68 SHOW_QUOTA_INFO="$LFS quota -t $DIR"
69
70 # control the time of tests
71 cycle=30
72 [ "$SLOW" = "no" ] && cycle=10
73
74 build_test_filter
75
76 eval ONLY_0=true
77 eval ONLY_99=true
78
79 # set_blk_tunables(btune_sz)
80 set_blk_tunesz() {
81         # set btune size on all obdfilters
82         do_facet ost1 "set -x; for i in /proc/fs/lustre/obdfilter/*/quota_btune_sz; do
83                 echo $(($1 * BLK_SZ)) >> \\\$i;
84         done"
85         # set btune size on mds
86         do_facet $SINGLEMDS "for i in /proc/fs/lustre/mds/${FSNAME}-MDT*/quota_btune_sz; do
87                 echo $(($1 * BLK_SZ)) >> \\\$i;
88         done"
89 }
90
91 # set_blk_unitsz(bunit_sz)
92 set_blk_unitsz() {
93         do_facet ost1 "for i in /proc/fs/lustre/obdfilter/*/quota_bunit_sz; do
94                 echo $(($1 * BLK_SZ)) >> \\\$i;
95         done"
96         do_facet $SINGLEMDS "for i in /proc/fs/lustre/mds/${FSNAME}-MDT*/quota_bunit_sz; do
97                 echo $(($1 * BLK_SZ)) >> \\\$i;
98         done"
99 }
100
101 # set_file_tunesz(itune_sz)
102 set_file_tunesz() {
103         # set iunit and itune size on all obdfilters
104         do_facet ost1 "for i in /proc/fs/lustre/obdfilter/*/quota_itune_sz; do
105                 echo $1 >> \\\$i;
106         done"
107         # set iunit and itune size on mds
108         do_facet $SINGLEMDS "for i in /proc/fs/lustre/mds/${FSNAME}-MDT*/quota_itune_sz; do
109                 echo $1 >> \\\$i;
110         done"
111 }
112
113 # set_file_unitsz(iunit_sz)
114 set_file_unitsz() {
115         do_facet ost1 "for i in /proc/fs/lustre/obdfilter/*/quota_iunit_sz; do
116                 echo $1 >> \\\$i;
117         done"
118         do_facet $SINGLEMDS "for i in /proc/fs/lustre/mds/${FSNAME}-MDT*/quota_iunit_sz; do
119                 echo $1 >> \\\$i;
120         done"
121 }
122
123 # These are for test on local machine,if run sanity-quota.sh on 
124 # real cluster, ltest should have setup the test environment: 
125 #
126 # - create test user/group on all servers with same id.
127 # - set unit size/tune on all servers size to reasonable value.
128 pre_test() {
129         if [ -z "$NOSETUP" ]; then
130                 # set block tunables
131                 set_blk_tunesz $BTUNE_SZ
132                 set_blk_unitsz $BUNIT_SZ
133                 # set file tunables
134                 set_file_tunesz $ITUNE_SZ
135                 set_file_unitsz $IUNIT_SZ
136         fi
137 }
138 pre_test
139
140 post_test() {
141         if [ -z "$NOSETUP" ]; then
142                 # restore block tunables to default size
143                 set_blk_unitsz $((1024 * 100))
144                 set_blk_tunesz $((1024 * 50))
145                 # restore file tunables to default size
146                 set_file_unitsz 5000
147                 set_file_tunesz 2500
148         fi
149 }
150
151 RUNAS="runas -u $TSTID"
152 RUNAS2="runas -u $TSTID2"
153 FAIL_ON_ERROR=true check_runas_id $TSTID $RUNAS
154 FAIL_ON_ERROR=true check_runas_id $TSTID2 $RUNAS2
155
156 FAIL_ON_ERROR=false
157
158 # set quota
159 test_0() {
160         $LFS quotaoff -ug $DIR
161         $LFS quotacheck -ug $DIR
162
163         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
164         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
165 }
166 run_test 0 "Set quota ============================="
167
168 # block hard limit (normal use and out of quota)
169 test_1() {
170         mkdir -p $DIR/$tdir
171         chmod 0777 $DIR/$tdir
172
173         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 5)) # 5 bunits each sever
174         TESTFILE=$DIR/$tdir/$tfile-0    
175         
176         echo "  User quota (limit: $LIMIT kbytes)"
177         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
178         $SHOW_QUOTA_USER
179         
180         $LFS setstripe $TESTFILE -c 1
181         chown $TSTUSR.$TSTUSR $TESTFILE
182
183         echo "    Write ..."
184         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) || error "(usr) write failure, but expect success"
185         echo "    Done"
186         echo "    Write out of block quota ..."
187         # this time maybe cache write,  ignore it's failure
188         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) seek=$(($LIMIT/2)) || true
189         # flush cache, ensure noquota flag is setted on client
190         sync; sleep 1; sync;
191         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$LIMIT && error "(usr) write success, but expect EDQUOT"
192
193         rm -f $TESTFILE
194         
195         echo "  Group quota (limit: $LIMIT kbytes)"
196         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
197         $LFS setquota -g $TSTUSR 0 $LIMIT 0 0 $DIR
198         $SHOW_QUOTA_GROUP
199         TESTFILE=$DIR/$tdir/$tfile-1    
200
201         $LFS setstripe $TESTFILE -c 1
202         chown $TSTUSR.$TSTUSR $TESTFILE
203
204         echo "    Write ..."
205         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) || error "(grp) write failure, but expect success"
206         echo "    Done"
207         echo "    Write out of block quota ..."
208         # this time maybe cache write, ignore it's failure
209         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) seek=$(($LIMIT/2)) || true
210         sync; sleep 1; sync;
211         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$LIMIT && error "(grp) write success, but expect EDQUOT"
212
213         # cleanup
214         rm -f $TESTFILE
215         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
216 }
217 run_test 1 "Block hard limit (normal use and out of quota) ==="
218
219 # file hard limit (normal use and out of quota)
220 test_2() {
221         mkdir -p $DIR/$tdir
222         chmod 0777 $DIR/$tdir
223
224         LIMIT=$(($IUNIT_SZ * 10)) # 10 iunits on mds
225         TESTFILE=$DIR/$tdir/$tfile-0    
226
227         echo "  User quota (limit: $LIMIT files)"
228         $LFS setquota -u $TSTUSR 0 0 0 $LIMIT $DIR
229         $SHOW_QUOTA_USER
230
231         echo "    Create $LIMIT files ..."
232         $RUNAS createmany -m ${TESTFILE} $LIMIT || \
233             error "(usr) create failure, but expect success"
234         echo "    Done"
235         echo "    Create out of file quota ..."
236         $RUNAS touch ${TESTFILE}_xxx && \
237                 error "(usr) touch success, but expect EDQUOT"
238
239         unlinkmany ${TESTFILE} $LIMIT
240         rm ${TESTFILE}_xxx
241
242         echo "  Group quota (limit: $LIMIT files)"
243         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
244         $LFS setquota -g $TSTUSR 0 0 0 $LIMIT $DIR
245         $SHOW_QUOTA_GROUP
246         TESTFILE=$DIR/$tdir/$tfile-1
247
248         echo "    Create $LIMIT files ..."
249         $RUNAS createmany -m ${TESTFILE} $LIMIT || \
250                 error "(grp) create failure, but expect success"
251
252         echo "    Done"
253         echo "    Create out of file quota ..."
254         $RUNAS touch ${TESTFILE}_xxx && \
255                 error "(grp) touch success, but expect EDQUOT"
256
257         $RUNAS touch ${TESTFILE}_xxx > /dev/null 2>&1 && error "(grp) touch success, but expect EDQUOT"
258
259         # cleanup
260         unlinkmany ${TESTFILE} $LIMIT
261         rm ${TESTFILE}_xxx
262
263         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
264 }
265 run_test 2 "File hard limit (normal use and out of quota) ==="
266
267 test_block_soft() {
268         TESTFILE=$1
269         TIMER=$(($2 * 3 / 2))
270         OFFSET=0
271
272         echo "    Write to exceed soft limit"
273         RUNDD="$RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ"
274         $RUNDD count=$((BUNIT_SZ+1)) || \
275                 error "write failure, but expect success"
276         OFFSET=$((OFFSET + BUNIT_SZ + 1))
277         sync; sleep 1; sync;
278
279         $SHOW_QUOTA_USER
280         $SHOW_QUOTA_GROUP
281         $SHOW_QUOTA_INFO
282
283         echo "    Write before timer goes off"
284         $RUNDD count=$BUNIT_SZ seek=$OFFSET || \
285                 error "write failure, but expect success"
286         OFFSET=$((OFFSET + BUNIT_SZ))
287         sync; sleep 1; sync;
288         echo "    Done"
289         
290         echo "    Sleep $TIMER seconds ..."
291         sleep $TIMER
292
293         $SHOW_QUOTA_USER
294         $SHOW_QUOTA_GROUP
295         $SHOW_QUOTA_INFO
296
297         echo "    Write after timer goes off"
298         # maybe cache write, ignore.
299         sync; sleep 1; sync;
300         $RUNDD count=$BUNIT_SZ seek=$OFFSET || true
301         OFFSET=$((OFFSET + BUNIT_SZ))
302         sync; sleep 1; sync;
303         $RUNDD count=$BUNIT_SZ seek=$OFFSET && \
304                 error "write success, but expect EDQUOT"
305
306         $SHOW_QUOTA_USER
307         $SHOW_QUOTA_GROUP
308         $SHOW_QUOTA_INFO
309
310         echo "    Unlink file to stop timer"
311         rm -f $TESTFILE
312         echo "    Done"
313
314         $SHOW_QUOTA_USER
315         $SHOW_QUOTA_GROUP
316         $SHOW_QUOTA_INFO
317
318         echo "    Write ..."
319         $RUNDD count=$BUNIT_SZ || error "write failure, but expect success"
320         echo "    Done"
321
322         # cleanup
323         rm -f $TESTFILE
324 }
325
326 # block soft limit (start timer, timer goes off, stop timer)
327 test_3() {
328         mkdir -p $DIR/$tdir
329         chmod 0777 $DIR/$tdir
330
331         LIMIT=$(( $BUNIT_SZ * 2 )) # 1 bunit on mds and 1 bunit on the ost
332         GRACE=10
333
334         echo "  User quota (soft limit: $LIMIT kbytes  grace: $GRACE seconds)"
335         TESTFILE=$DIR/$tdir/$tfile-0
336
337         $LFS setstripe $TESTFILE -c 1
338         chown $TSTUSR.$TSTUSR $TESTFILE
339
340         $LFS setquota -t -u $GRACE $MAX_IQ_TIME $DIR
341         $LFS setquota -u $TSTUSR $LIMIT 0 0 0 $DIR
342
343         test_block_soft $TESTFILE $GRACE
344         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
345
346         echo "  Group quota (soft limit: $LIMIT kbytes  grace: $GRACE seconds)"
347         TESTFILE=$DIR/$tdir/$tfile-1
348
349         $LFS setstripe $TESTFILE -c 1
350         chown $TSTUSR.$TSTUSR $TESTFILE
351
352         $LFS setquota -t -g $GRACE $MAX_IQ_TIME $DIR
353         $LFS setquota -g $TSTUSR $LIMIT 0 0 0 $DIR
354
355         test_block_soft $TESTFILE $GRACE
356         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
357 }
358 run_test 3 "Block soft limit (start timer, timer goes off, stop timer) ==="
359
360 test_file_soft() {
361         TESTFILE=$1
362         LIMIT=$2
363         TIMER=$(($3 * 3 / 2))
364
365         echo "    Create files to exceed soft limit"
366         $RUNAS createmany -m ${TESTFILE}_ $((LIMIT + 1)) || \
367                 error "create failure, but expect success"
368         sync; sleep 1; sync
369         echo "    Done"
370
371         echo "    Create file before timer goes off"
372         $RUNAS touch ${TESTFILE}_before || \
373                 error "failed create before timer expired, but expect success"
374         sync; sleep 1; sync
375         echo "    Done"
376
377         echo "    Sleep $TIMER seconds ..."
378         sleep $TIMER
379         
380         $SHOW_QUOTA_USER
381         $SHOW_QUOTA_GROUP
382         $SHOW_QUOTA_INFO
383         
384         echo "    Create file after timer goes off"
385         $RUNAS createmany -m ${TESTFILE}_after_ $((IUNIT_SZ - 2)) || \
386                 error "create ${TESTFILE}_after failure, but expect success"
387         sync; sleep 1; sync
388         $RUNAS touch ${TESTFILE}_after && \
389                 error "create after timer expired, but expect EDQUOT"
390         sync; sleep 1; sync
391
392         $SHOW_QUOTA_USER
393         $SHOW_QUOTA_GROUP
394         $SHOW_QUOTA_INFO
395         
396         echo "    Unlink files to stop timer"
397         find `dirname $TESTFILE` -name "`basename ${TESTFILE}`*" | xargs rm -f
398         echo "    Done"
399
400         echo "    Create file"
401         $RUNAS touch ${TESTFILE}_xxx || \
402                 error "touch after timer stop failure, but expect success"
403         sync; sleep 1; sync
404         echo "    Done"
405
406         # cleanup
407         rm -f ${TESTFILE}_xxx
408 }
409
410 # file soft limit (start timer, timer goes off, stop timer)
411 test_4a() {     # was test_4
412         mkdir -p $DIR/$tdir
413         chmod 0777 $DIR/$tdir
414         LIMIT=$(($IUNIT_SZ * 10))       # 10 iunits on mds
415         TESTFILE=$DIR/$tdir/$tfile-0
416
417         GRACE=5
418
419         echo "  User quota (soft limit: $LIMIT files  grace: $GRACE seconds)"
420         $LFS setquota -t -u $MAX_DQ_TIME $GRACE $DIR
421         $LFS setquota -u $TSTUSR 0 0 $LIMIT 0 $DIR
422         $SHOW_QUOTA_USER
423
424         test_file_soft $TESTFILE $LIMIT $GRACE
425         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
426
427         echo "  Group quota (soft limit: $LIMIT files  grace: $GRACE seconds)"
428         $LFS setquota -t -g $MAX_DQ_TIME $GRACE $DIR
429         $LFS setquota -g $TSTUSR 0 0 $LIMIT 0 $DIR
430         $SHOW_QUOTA_GROUP
431         TESTFILE=$DIR/$tdir/$tfile-1
432
433         test_file_soft $TESTFILE $LIMIT $GRACE
434         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
435
436         # cleanup
437         $LFS setquota -t -u $MAX_DQ_TIME $MAX_IQ_TIME $DIR
438         $LFS setquota -t -g $MAX_DQ_TIME $MAX_IQ_TIME $DIR
439 }
440 run_test 4a "File soft limit (start timer, timer goes off, stop timer) ==="
441
442 test_4b() {     # was test_4a
443         GR_STR1="1w3d"
444         GR_STR2="1000s"
445         GR_STR3="5s"
446         GR_STR4="1w2d3h4m5s"
447         GR_STR5="5c"
448         GR_STR6="1111111111111111"
449
450         # test of valid grace strings handling
451         echo "  Valid grace strings test"
452         $LFS setquota -t -u $GR_STR1 $GR_STR2 $DIR
453         $LFS quota -u -t $DIR | grep "Block grace time: $GR_STR1"
454         $LFS setquota -t -g $GR_STR3 $GR_STR4 $DIR
455         $LFS quota -g -t $DIR | grep "Inode grace time: $GR_STR4"
456
457         # test of invalid grace strings handling
458         echo "  Invalid grace strings test"
459         ! $LFS setquota -t -u $GR_STR4 $GR_STR5 $DIR
460         ! $LFS setquota -t -g $GR_STR4 $GR_STR6 $DIR
461
462         # cleanup
463         $LFS setquota -t -u $MAX_DQ_TIME $MAX_IQ_TIME $DIR
464         $LFS setquota -t -g $MAX_DQ_TIME $MAX_IQ_TIME $DIR
465 }
466 run_test 4b "Grace time strings handling ==="
467
468 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
469 test_5() {
470         mkdir -p $DIR/$tdir
471         BLIMIT=$(( $BUNIT_SZ * $((OSTCOUNT + 1)) * 10)) # 10 bunits on each server
472         ILIMIT=$(( $IUNIT_SZ * 10 )) # 10 iunits on mds
473         
474         echo "  Set quota limit (0 $BLIMIT 0 $ILIMIT) for $TSTUSR.$TSTUSR"
475         $LFS setquota -u $TSTUSR 0 $BLIMIT 0 $ILIMIT $DIR
476         $LFS setquota -g $TSTUSR 0 $BLIMIT 0 $ILIMIT $DIR
477         $SHOW_QUOTA_USER
478         $SHOW_QUOTA_GROUP
479         
480         echo "  Create more than $ILIMIT files and more than $BLIMIT kbytes ..."
481         createmany -m $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) || \
482                 error "touch failure, expect success"
483         dd if=/dev/zero of=$DIR/$tdir/$tfile-0_1 bs=$BLK_SZ count=$((BLIMIT+1)) || error "write failure, expect success"
484
485         echo "  Chown files to $TSTUSR.$TSTUSR ..."
486         for i in `seq 0 $ILIMIT`; do
487         chown $TSTUSR.$TSTUSR $DIR/$tdir/$tfile-0_$i || \
488                         error "chown failure, but expect success"
489         done
490
491         # cleanup
492         unlinkmany $DIR/$tdir/$tfile-0_ $((ILIMIT + 1))
493
494         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
495         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
496 }
497 run_test 5 "Chown & chgrp successfully even out of block/file quota ==="
498
499 # block quota acquire & release
500 test_6() {
501         if [ $OSTCOUNT -lt 2 ]; then
502                 skip "$OSTCOUNT < 2, too few osts"
503                 return 0;
504         fi
505
506         mkdir -p $DIR/$tdir
507         chmod 0777 $DIR/$tdir
508
509         LIMIT=$((BUNIT_SZ * (OSTCOUNT + 1) * 5)) # 5 bunits per server
510         FILEA="$DIR/$tdir/$tfile-0_a"
511         FILEB="$DIR/$tdir/$tfile-0_b"
512         
513         echo "  Set block limit $LIMIT kbytes to $TSTUSR.$TSTUSR"
514         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
515         $LFS setquota -g $TSTUSR 0 $LIMIT 0 0 $DIR
516         $SHOW_QUOTA_USER
517         $SHOW_QUOTA_GROUP
518
519         echo "  Create filea on OST0 and fileb on OST1"
520         $LFS setstripe $FILEA -i 0 -c 1
521         $LFS setstripe $FILEB -i 1 -c 1
522         chown $TSTUSR.$TSTUSR $FILEA
523         chown $TSTUSR.$TSTUSR $FILEB
524
525         echo "  Exceed quota limit ..."
526         RUNDD="$RUNAS dd if=/dev/zero of=$FILEB bs=$BLK_SZ"
527         $RUNDD count=$((LIMIT - BUNIT_SZ * OSTCOUNT)) || \
528                 error "write fileb failure, but expect success"
529
530         sync; sleep 1; sync;
531         $SHOW_QUOTA_USER
532         $SHOW_QUOTA_GROUP
533         $RUNDD seek=$LIMIT count=$((BUNIT_SZ * OSTCOUNT)) && \
534                 error "write fileb success, but expect EDQUOT"
535         sync; sleep 1; sync;
536         echo "  Write to OST0 return EDQUOT"
537         # this write maybe cache write, ignore it's failure
538         RUNDD="$RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ"
539         $RUNDD count=$(($BUNIT_SZ * 2)) || true
540         sync; sleep 1; sync;
541         $SHOW_QUOTA_USER
542         $SHOW_QUOTA_GROUP
543         $RUNDD count=$((BUNIT_SZ * 2)) seek=$((BUNIT_SZ *2)) && \
544                 error "write filea success, but expect EDQUOT"
545
546         echo "  Remove fileb to let OST1 release quota"
547         rm -f $FILEB
548         sync; sleep 10; sync; # need to allow journal commit for small fs
549
550         echo "  Write to OST0"
551         $RUNDD count=$((LIMIT - BUNIT_SZ * OSTCOUNT)) || \
552                 error "write filea failure, expect success"
553         echo "  Done"
554
555         # cleanup
556         rm -f $FILEA
557         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
558         $LFS setquota -g $TSTUSR 0 0 0 0 $DIR
559         return 0
560 }
561 run_test 6 "Block quota acquire & release ========="
562
563 # quota recovery (block quota only by now)
564 test_7()
565 {
566         mkdir -p $DIR/$tdir
567         chmod 0777 $DIR/$tdir
568         remote_mds && skip "remote mds" && return 0
569
570         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
571         TESTFILE="$DIR/$tdir/$tfile-0"
572         
573         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
574         
575         $LFS setstripe $TESTFILE -c 1
576         chown $TSTUSR.$TSTUSR $TESTFILE
577
578         echo "  Write to OST0..."
579         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ || \
580                 error "write failure, but expect success"
581         
582         #define OBD_FAIL_OBD_DQACQ               0x604
583         echo 0x604 > /proc/sys/lustre/fail_loc
584         echo "  Remove files on OST0"
585         rm -f $TESTFILE
586         echo 0 > /proc/sys/lustre/fail_loc
587
588         echo "  Trigger recovery..."
589         OSC0_UUID="`$LCTL dl | awk '$3 ~ /osc/ { print $1 }'`"
590         for i in $OSC0_UUID; do
591                 $LCTL --device $i activate || error "activate osc failed!"
592         done
593
594         # sleep a while to wait for recovery done
595         sleep 20
596
597         # check limits
598         PATTERN="`echo $DIR | sed 's/\//\\\\\//g'`"
599         TOTAL_LIMIT="`$LFS quota -u $TSTUSR $DIR | awk '/^.*'$PATTERN'.*[[:digit:]+][[:space:]+]/ { print $4 }'`"
600         [ $TOTAL_LIMIT -eq $LIMIT ] || error "total limits not recovery!"
601         echo "  total limits = $TOTAL_LIMIT"
602         
603         OST0_UUID=`do_facet ost1 "$LCTL dl | grep -m1 obdfilter" | awk '{print $((NF-1))}'`
604         [ -z "$OST0_UUID" ] && OST0_UUID=`do_facet ost1 "$LCTL dl | grep -m1 obdfilter" | awk '{print $((NF-1))}'`
605         OST0_LIMIT="`$LFS quota -o $OST0_UUID -u $TSTUSR $DIR | awk '/^.*[[:digit:]+][[:space:]+]/ { print $3 }'`"
606         [ $OST0_LIMIT -eq $BUNIT_SZ ] || error "high limits not released!"
607         echo "  limits on $OST0_UUID = $OST0_LIMIT"
608
609         # cleanup
610         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
611 }
612 run_test 7 "Quota recovery (only block limit) ======"
613
614 # run dbench with quota enabled
615 test_8() {
616         mkdir -p $DIR/$tdir
617         BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
618         FILE_LIMIT=1000000
619         DBENCH_LIB=${DBENCH_LIB:-/usr/lib/dbench}
620         
621         [ ! -d $DBENCH_LIB ] && skip "dbench not installed" && return 0
622
623         wait_delete_completed
624         
625         echo "  Set enough high limit for user: $TSTUSR"
626         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
627         echo "  Set enough high limit for group: $TSTUSR"
628         $LFS setquota -g $USER 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
629
630         TGT=$DIR/$tdir/client.txt
631         SRC=${SRC:-$DBENCH_LIB/client.txt}
632         [ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT
633         SRC=$DBENCH_LIB/client_plain.txt
634         [ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT
635
636         mkdir -p $DIR/$tdir
637         chmod 0777 $DIR/$tdir
638         SAVE_PWD=$PWD
639         cd $DIR/$tdir
640         local duration=""
641         [ "$SLOW" = "no" ] && duration=" -t 120"
642         $RUNAS dbench -c client.txt 3 $duration
643         RC=$?
644         [ $RC -ne 0 ] && killall -9 dbench
645         
646         rm -f client.txt
647         sync; sleep 3; sync;
648
649         cd $SAVE_PWD
650         return $RC
651 }
652 run_test 8 "Run dbench with quota enabled ==========="
653
654 # run for fixing bug10707, it needs a big room. test for 64bit
655 KB=1024
656 GB=$((KB * 1024 * 1024))
657 FSIZE=$((OSTCOUNT * 9 / 2))
658 # Use this as dd bs to decrease time
659 # inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS+1, LL_MAX_BLKSIZE_BITS);
660 blksize=$((1 << 21)) # 2Mb
661
662 test_9() {
663         chmod 0777 $DIR/$tdir
664         lustrefs_size=`(echo 0; df -t lustre -P | awk '{print $4}') | tail -n 1`
665         size_file=$((FSIZE * GB))
666         echo "lustrefs_size:$lustrefs_size  size_file:$((size_file / KB))"
667         if [ $((lustrefs_size * KB)) -lt $size_file ]; then
668                 skip "less than $size_file bytes free"
669                 return 0;
670         fi
671
672         set_blk_unitsz $((1024 * 100))
673         set_blk_tunesz $((1024 * 50))
674
675         # set the D_QUOTA flag
676         debugsave
677         sysctl -w lnet.debug="+quota"
678
679         TESTFILE="$DIR/$tdir/$tfile-0"
680
681         BLK_LIMIT=$((100 * KB * KB)) # 100G
682         FILE_LIMIT=1000000
683
684         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
685         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
686         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
687         $LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
688
689         echo "  Set stripe"
690         [ $OSTCOUNT -ge 2 ] && $LFS setstripe $TESTFILE -c $OSTCOUNT
691         touch $TESTFILE
692         chown $TSTUSR.$TSTUSR $TESTFILE
693
694         $SHOW_QUOTA_USER
695         $SHOW_QUOTA_GROUP
696
697         echo "    Write the big file of $FSIZE G ..."
698         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((size_file / blksize)) || \
699                error "(usr) write $FSIZE G file failure, but expect success"
700
701         $SHOW_QUOTA_USER
702         $SHOW_QUOTA_GROUP
703
704         echo "    delete the big file of $FSIZE G..." 
705         $RUNAS rm -f $TESTFILE
706
707         $SHOW_QUOTA_USER
708         $SHOW_QUOTA_GROUP
709
710         echo "    write the big file of 2 G..."
711         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((2 * GB / blksize)) || \
712                error "(usr) write 2 G file failure, but expect seccess"
713
714         echo "    delete the big file of 2 G..."
715         $RUNAS rm -f $TESTFILE 
716         RC=$?
717
718         set_blk_tunesz $BTUNE_SZ
719         set_blk_unitsz $BUNIT_SZ
720
721         debugrestore
722         wait_delete_completed
723
724         return $RC
725 }
726 run_test 9 "run for fixing bug10707(64bit) ==========="
727
728 # run for fixing bug10707, it need a big room. test for 32bit
729 test_10() {
730         mkdir -p $DIR/$tdir
731         chmod 0777 $DIR/$tdir
732         lustrefs_size=`(echo 0; df -t lustre -P | awk '{print $4}') | tail -n 1`
733         size_file=$((FSIZE * GB))
734         echo "lustrefs_size:$lustrefs_size  size_file:$((size_file / KB))"
735         if [ $((lustrefs_size * KB)) -lt $size_file ]; then
736                 skip "less than $size_file bytes free"
737                 return 0;
738         fi
739
740         sync; sleep 10; sync;
741
742         set_blk_unitsz $((1024 * 100))
743         set_blk_tunesz $((1024 * 50))
744
745         # set the D_QUOTA flag
746         debugsave
747         sysctl -w lnet.debug="+quota"
748         
749         # make qd_count 32 bit
750         sysctl -w lustre.fail_loc=0xA00
751
752         TESTFILE="$DIR/$tdir/$tfile-0"
753
754         BLK_LIMIT=$((100 * KB * KB)) # 100G
755         FILE_LIMIT=1000000
756
757         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
758         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
759         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
760         $LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
761        
762         echo "  Set stripe"
763         [ $OSTCOUNT -ge 2 ] && $LFS setstripe $TESTFILE -c $OSTCOUNT
764         touch $TESTFILE
765         chown $TSTUSR.$TSTUSR $TESTFILE
766
767         $SHOW_QUOTA_USER
768         $SHOW_QUOTA_GROUP
769
770         echo "    Write the big file of $FSIZE G ..."
771         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((size_file / blksize)) || \
772                 error "(usr) write $FSIZE G file failure, but expect success"
773  
774         $SHOW_QUOTA_USER
775         $SHOW_QUOTA_GROUP
776
777         echo "    delete the big file of $FSIZE G..."
778         $RUNAS rm -f $TESTFILE 
779
780         $SHOW_QUOTA_USER
781         $SHOW_QUOTA_GROUP
782
783         echo "    write the big file of 2 G..."
784         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((2 * GB / blkzise)) || \
785                 error "(usr) write 2 G file failure, but expect success" 
786
787         echo "    delete the big file of 2 G..."
788         $RUNAS rm -f $TESTFILE 
789
790         RC=$?
791
792         # clear the flage
793         debugrestore
794
795         # make qd_count 64 bit
796         sysctl -w lustre.fail_loc=0
797
798         set_blk_tunesz $BTUNE_SZ
799         set_blk_unitsz $BUNIT_SZ
800
801         wait_delete_completed
802
803         return $RC
804 }
805 run_test 10 "run for fixing bug10707(32bit) ==========="
806
807 test_11() {
808        wait_delete_completed
809
810        #prepare the test
811        block_limit=`(echo 0; df -t lustre -P | awk '{print $(NF - 4)}') | tail -n 1`
812        echo $block_limit
813        orig_dbr=`cat /proc/sys/vm/dirty_background_ratio`
814        orig_dec=`cat /proc/sys/vm/dirty_expire_centisecs`
815        orig_dr=`cat /proc/sys/vm/dirty_ratio`
816        orig_dwc=`cat /proc/sys/vm/dirty_writeback_centisecs`
817        echo 1  > /proc/sys/vm/dirty_background_ratio
818        echo 30 > /proc/sys/vm/dirty_expire_centisecs
819        echo 1  > /proc/sys/vm/dirty_ratio
820        echo 50 > /proc/sys/vm/dirty_writeback_centisecs
821        TESTDIR="$DIR/$tdir"
822        local RV=0
823
824        #do the test
825        local SECS=0
826        local REPS=3
827        [ "$SLOW" = no ] && REPS=1
828        local sleep=20
829        local i=1
830        while [ $i -le $REPS ]; do
831            echo "test: cycle($i of $REPS) start at $(date)"
832            mkdir -p $TESTDIR && chmod 777 $TESTDIR
833            echo -n "    create a file for uid "
834            for j in `seq 1 30`; do
835                echo -n "$j "
836                # 30MB per dd for a total of 900MB (if space even permits)
837                runas -u $j dd if=/dev/zero of=$TESTDIR/$tfile  bs=$blksize count=15 > /dev/null 2>&1 &
838            done
839            echo ""
840            PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
841            LAST_USED=0
842            while [ $PROCS -gt 0 ]; do 
843              sleep 20
844              SECS=$((SECS + sleep))
845              PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
846              USED=$(du -s $TESTDIR | awk '{print $1}')
847              PCT=$(($USED * 100 / $block_limit))
848              echo "${i}/${REPS} ${PCT}% p${PROCS} t${SECS}  "
849              if [ $USED -le $LAST_USED ]; then
850                  kill -9 $(ps -ef | grep "dd if /dev/zero of $TESTDIR" | grep -v grep | awk '{ print $2 }')
851                  i=$REPS
852                  RV=2
853                  break
854              fi
855              LAST_USED=$USED
856            done
857            echo "    removing the test files..."
858            rm -f $TESTDIR/$tfile
859            echo "cycle $i done at $(date)"
860            i=$[$i+1]
861        done
862        echo "Test took $SECS sec"
863
864        #clean
865        echo $orig_dbr > /proc/sys/vm/dirty_background_ratio
866        echo $orig_dec > /proc/sys/vm/dirty_expire_centisecs
867        echo $orig_dr  > /proc/sys/vm/dirty_ratio
868        echo $orig_dwc > /proc/sys/vm/dirty_writeback_centisecs
869        if [ $RV -ne 0 ]; then
870            error "Nothing was written for $SECS sec ... aborting"
871        fi
872        return $RV
873 }
874 run_test 11 "run for fixing bug10912 ==========="
875
876
877 # test a deadlock between quota and journal b=11693
878 test_12() {
879         mkdir -p $DIR/$tdir
880         chmod 0777 $DIR/$tdir
881
882         [ "$(grep $DIR2 /proc/mounts)" ] || mount_client $DIR2 || \
883                 { skip "Need lustre mounted on $MOUNT2 " && retutn 0; }
884
885         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
886         TESTFILE="$DIR/$tdir/$tfile-0"
887         TESTFILE2="$DIR2/$tdir/$tfile-1"
888         
889         echo "   User quota (limit: $LIMIT kbytes)"
890         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
891
892         $LFS setstripe $TESTFILE -i 0 -c 1 
893         chown $TSTUSR.$TSTUSR $TESTFILE
894         $LFS setstripe $TESTFILE2 -i 0 -c 1
895         chown $TSTUSR2.$TSTUSR2 $TESTFILE2
896
897         #define OBD_FAIL_OST_HOLD_WRITE_RPC      0x21f
898         sysctl -w lustre.fail_loc=0x0000021f        
899
900         echo "   step1: write out of block quota ..."
901         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT*2)) & 
902         DDPID=$!
903         sleep 5
904         $RUNAS2 dd if=/dev/zero of=$TESTFILE2 bs=$BLK_SZ count=102400 & 
905         DDPID1=$!
906
907         echo  "   step2: testing ......"
908         count=0
909         while [ true ]; do
910             if [ -z `ps -ef | awk '$2 == '${DDPID1}' { print $8 }'` ]; then break; fi
911             count=$[count+1]
912             if [ $count -gt 64 ]; then
913                 sysctl -w lustre.fail_loc=0
914                 error "dd should be finished!"
915             fi
916             sleep 1
917         done    
918         echo "(dd_pid=$DDPID1, time=$count)successful"
919
920         #Recover fail_loc and dd will finish soon
921         sysctl -w lustre.fail_loc=0
922
923         echo  "   step3: testing ......"
924         count=0
925         while [ true ]; do
926             if [ -z `ps -ef | awk '$2 == '${DDPID}' { print $8 }'` ]; then break; fi
927             count=$[count+1]
928             if [ $count -gt 100 ]; then
929                 error "dd should be finished!"
930             fi
931             sleep 1
932         done    
933         echo "(dd_pid=$DDPID, time=$count)successful"
934
935         rm -f $TESTFILE $TESTFILE2
936         
937         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
938 }
939 run_test 12 "test a deadlock between quota and journal ==="
940
941 # test multiple clients write block quota b=11693
942 test_13() {
943         # one OST * 10 + (mds + other OSTs)
944         LIMIT=$((BUNIT_SZ * 10 + (BUNIT_SZ * OSTCOUNT)))
945         TESTFILE="$DIR/$tdir/$tfile"
946         mkdir -p $DIR/$tdir
947
948         echo "   User quota (limit: $LIMIT kbytes)"
949         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
950         $SHOW_QUOTA_USER
951         
952         $LFS setstripe $TESTFILE -i 0 -c 1
953         chown $TSTUSR.$TSTUSR $TESTFILE
954         $LFS setstripe $TESTFILE.2 -i 0 -c 1
955         chown $TSTUSR.$TSTUSR $TESTFILE.2
956
957         echo "   step1: write out of block quota ..."
958         # one bunit will give mds
959         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$[($LIMIT - $BUNIT_SZ) / 2] & 
960         DDPID=$!
961         $RUNAS dd if=/dev/zero of=$TESTFILE.2 bs=$BLK_SZ count=$[($LIMIT - $BUNIT_SZ) / 2] & 
962         DDPID1=$!
963
964         echo  "   step2: testing ......"
965         count=0
966         while [ true ]; do
967             if [ -z `ps -ef | awk '$2 == '${DDPID}' { print $8 }'` ]; then break; fi
968             count=$[count+1]
969             if [ $count -gt 64 ]; then
970                 error "dd should be finished!"
971             fi
972             sleep 1
973         done    
974         echo "(dd_pid=$DDPID, time=$count)successful"
975
976         count=0
977         while [ true ]; do
978             if [ -z `ps -ef | awk '$2 == '${DDPID1}' { print $8 }'` ]; then break; fi
979             count=$[count+1]
980             if [ $count -gt 64 ]; then
981                 error "dd should be finished!"
982             fi
983             sleep 1
984         done    
985         echo "(dd_pid=$DDPID1, time=$count)successful"
986
987         sync; sleep 5; sync;
988
989         echo  "   step3: checking ......"
990         fz=`stat -c %s $TESTFILE`
991         fz2=`stat -c %s $TESTFILE.2`
992         $SHOW_QUOTA_USER
993         [ $((fz + fz2)) -lt $((BUNIT_SZ * BLK_SZ * 10)) ] && \
994                 error "files too small $fz + $fz2 < $((BUNIT_SZ * BLK_SZ * 10))"
995
996         rm -f $TESTFILE $TESTFILE.2
997         
998         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
999 }
1000 run_test 13 "test multiple clients write block quota ==="
1001
1002 check_if_quota_zero(){
1003         line=`$LFS quota -$1 $2 $DIR | wc -l`
1004         for i in `seq 3 $line`; do
1005             if [ $i -eq 3 ]; then
1006                 field="3 4 6 7"
1007             else
1008                 field="3 5"
1009             fi
1010             for j in $field; do
1011                 tmp=`$LFS quota -$1 $2 $DIR | sed -n ${i}p | 
1012                      awk  '{print $'"$j"'}'`
1013                 [ -n "$tmp" ] && [ $tmp -ne 0 ] && $LFS quota -$1 $2 $DIR && \
1014                     error "quota on $2 isn't clean"
1015             done
1016         done
1017         echo "pass check_if_quota_zero"
1018 }
1019
1020 pre_test_14 () {
1021         # reboot the lustre
1022         cd $T_PWD; sh llmountcleanup.sh || error "llmountcleanup failed"
1023         sh llmount.sh
1024         pre_test
1025         run_test 0 "reboot lustre"
1026 }
1027
1028 pre_test_14 
1029
1030 test_14a() {    # was test_14 b=12223 -- setting quota on root
1031         TESTFILE="$DIR/$tdir/$tfile"
1032         mkdir -p $DIR/$tdir
1033
1034         # out of root's file and block quota
1035         $LFS setquota -u root 10 10 10 10 $DIR
1036         createmany -m ${TESTFILE} 20 || \
1037             error "unexpected: user(root) create files failly!"
1038         dd if=/dev/zero of=$TESTFILE bs=4k count=4096 || \
1039             error "unexpected: user(root) write files failly!"
1040         chmod 666 $TESTFILE
1041         $RUNAS dd if=/dev/zero of=${TESTFILE} seek=4096 bs=4k count=4096 && \
1042             error "unexpected: user(quota_usr) write a file successfully!"      
1043
1044         # trigger the llog
1045         chmod 777 $DIR
1046         for i in `seq 1 10`; do $RUNAS touch ${TESTFILE}a_$i; done 
1047         for i in `seq 1 10`; do $RUNAS rm -f ${TESTFILE}a_$i; done 
1048
1049         # do the check
1050         dmesg | tail | grep "\-122" |grep llog_obd_origin_add && error "err -122 not found in dmesg" 
1051         $LFS setquota -u root 0 0 0 0 $DIR
1052         #check_if_quota_zero u root
1053
1054         # clean 
1055         unlinkmany ${TESTFILE} 15
1056         rm -f $TESTFILE
1057 }
1058 run_test 14a "test setting quota on root ==="
1059
1060 # turn off quota
1061 test_99()
1062 {
1063         $LFS quotaoff $DIR
1064         return 0
1065 }
1066 run_test 99 "Quota off ==============================="
1067
1068
1069 log "cleanup: ======================================================"
1070 cd $ORIG_PWD
1071 post_test
1072 check_and_cleanup_lustre
1073 echo '=========================== finished ==============================='
1074 [ -f "$QUOTALOG" ] && cat $QUOTALOG && grep -q FAIL $QUOTALOG && exit 1 || true
1075 echo "$0: completed"