Whamcloud - gitweb
b=16637
[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
569         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
570         TESTFILE="$DIR/$tdir/$tfile-0"
571         
572         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
573         
574         $LFS setstripe $TESTFILE -c 1
575         chown $TSTUSR.$TSTUSR $TESTFILE
576
577         echo "  Write to OST0..."
578         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ || \
579                 error "write failure, but expect success"
580         
581         #define OBD_FAIL_OBD_DQACQ               0x604
582         echo 0x604 > /proc/sys/lustre/fail_loc
583         echo "  Remove files on OST0"
584         rm -f $TESTFILE
585         echo 0 > /proc/sys/lustre/fail_loc
586
587         echo "  Trigger recovery..."
588         OSC0_UUID="`$LCTL dl | awk '$3 ~ /osc/ { print $1 }'`"
589         for i in $OSC0_UUID; do
590                 $LCTL --device $i activate || error "activate osc failed!"
591         done
592
593         # sleep a while to wait for recovery done
594         sleep 20
595
596         # check limits
597         PATTERN="`echo $DIR | sed 's/\//\\\\\//g'`"
598         TOTAL_LIMIT="`$LFS quota -u $TSTUSR $DIR | awk '/^.*'$PATTERN'.*[[:digit:]+][[:space:]+]/ { print $4 }'`"
599         [ $TOTAL_LIMIT -eq $LIMIT ] || error "total limits not recovery!"
600         echo "  total limits = $TOTAL_LIMIT"
601         
602         OST0_UUID=`do_facet ost1 "$LCTL dl | grep -m1 obdfilter" | awk '{print $((NF-1))}'`
603         [ -z "$OST0_UUID" ] && OST0_UUID=`do_facet ost1 "$LCTL dl | grep -m1 obdfilter" | awk '{print $((NF-1))}'`
604         OST0_LIMIT="`$LFS quota -o $OST0_UUID -u $TSTUSR $DIR | awk '/^.*[[:digit:]+][[:space:]+]/ { print $3 }'`"
605         [ $OST0_LIMIT -eq $BUNIT_SZ ] || error "high limits not released!"
606         echo "  limits on $OST0_UUID = $OST0_LIMIT"
607
608         # cleanup
609         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR
610 }
611 run_test 7 "Quota recovery (only block limit) ======"
612
613 # run dbench with quota enabled
614 test_8() {
615         mkdir -p $DIR/$tdir
616         BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
617         FILE_LIMIT=1000000
618
619         wait_delete_completed
620
621         echo "  Set enough high limit for user: $TSTUSR"
622         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
623         echo "  Set enough high limit for group: $TSTUSR"
624         $LFS setquota -g $USER 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
625
626         chmod 0777 $DIR/$tdir
627         local duration=""
628         [ "$SLOW" = "no" ] && duration=" -t 120"
629         $RUNAS bash rundbench -D $DIR/$tdir 3 $duration || error "dbench failed!"
630
631         sync; sleep 3; sync;
632
633         return 0 
634 }
635 run_test 8 "Run dbench with quota enabled ==========="
636
637 # run for fixing bug10707, it needs a big room. test for 64bit
638 KB=1024
639 GB=$((KB * 1024 * 1024))
640 FSIZE=$((OSTCOUNT * 9 / 2))
641 # Use this as dd bs to decrease time
642 # inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS+1, LL_MAX_BLKSIZE_BITS);
643 blksize=$((1 << 21)) # 2Mb
644
645 test_9() {
646         chmod 0777 $DIR/$tdir
647         lustrefs_size=`(echo 0; df -t lustre -P | awk '{print $4}') | tail -n 1`
648         size_file=$((FSIZE * GB))
649         echo "lustrefs_size:$lustrefs_size  size_file:$((size_file / KB))"
650         if [ $((lustrefs_size * KB)) -lt $size_file ]; then
651                 skip "less than $size_file bytes free"
652                 return 0;
653         fi
654
655         set_blk_unitsz $((1024 * 100))
656         set_blk_tunesz $((1024 * 50))
657
658         # set the D_QUOTA flag
659         debugsave
660         sysctl -w lnet.debug="+quota"
661
662         TESTFILE="$DIR/$tdir/$tfile-0"
663
664         BLK_LIMIT=$((100 * KB * KB)) # 100G
665         FILE_LIMIT=1000000
666
667         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
668         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
669         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
670         $LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
671
672         echo "  Set stripe"
673         [ $OSTCOUNT -ge 2 ] && $LFS setstripe $TESTFILE -c $OSTCOUNT
674         touch $TESTFILE
675         chown $TSTUSR.$TSTUSR $TESTFILE
676
677         $SHOW_QUOTA_USER
678         $SHOW_QUOTA_GROUP
679
680         echo "    Write the big file of $FSIZE G ..."
681         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((size_file / blksize)) || \
682                error "(usr) write $FSIZE G file failure, but expect success"
683
684         $SHOW_QUOTA_USER
685         $SHOW_QUOTA_GROUP
686
687         echo "    delete the big file of $FSIZE G..." 
688         $RUNAS rm -f $TESTFILE
689
690         $SHOW_QUOTA_USER
691         $SHOW_QUOTA_GROUP
692
693         echo "    write the big file of 2 G..."
694         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((2 * GB / blksize)) || \
695                error "(usr) write 2 G file failure, but expect seccess"
696
697         echo "    delete the big file of 2 G..."
698         $RUNAS rm -f $TESTFILE 
699         RC=$?
700
701         set_blk_tunesz $BTUNE_SZ
702         set_blk_unitsz $BUNIT_SZ
703
704         debugrestore
705         wait_delete_completed
706
707         return $RC
708 }
709 run_test 9 "run for fixing bug10707(64bit) ==========="
710
711 # run for fixing bug10707, it need a big room. test for 32bit
712 test_10() {
713         mkdir -p $DIR/$tdir
714         chmod 0777 $DIR/$tdir
715         lustrefs_size=`(echo 0; df -t lustre -P | awk '{print $4}') | tail -n 1`
716         size_file=$((FSIZE * GB))
717         echo "lustrefs_size:$lustrefs_size  size_file:$((size_file / KB))"
718         if [ $((lustrefs_size * KB)) -lt $size_file ]; then
719                 skip "less than $size_file bytes free"
720                 return 0;
721         fi
722
723         sync; sleep 10; sync;
724
725         set_blk_unitsz $((1024 * 100))
726         set_blk_tunesz $((1024 * 50))
727
728         # set the D_QUOTA flag
729         debugsave
730         sysctl -w lnet.debug="+quota"
731         
732         # make qd_count 32 bit
733         sysctl -w lustre.fail_loc=0xA00
734
735         TESTFILE="$DIR/$tdir/$tfile-0"
736
737         BLK_LIMIT=$((100 * KB * KB)) # 100G
738         FILE_LIMIT=1000000
739
740         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
741         $LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
742         echo "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
743         $LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $DIR
744        
745         echo "  Set stripe"
746         [ $OSTCOUNT -ge 2 ] && $LFS setstripe $TESTFILE -c $OSTCOUNT
747         touch $TESTFILE
748         chown $TSTUSR.$TSTUSR $TESTFILE
749
750         $SHOW_QUOTA_USER
751         $SHOW_QUOTA_GROUP
752
753         echo "    Write the big file of $FSIZE G ..."
754         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((size_file / blksize)) || \
755                 error "(usr) write $FSIZE G file failure, but expect success"
756  
757         $SHOW_QUOTA_USER
758         $SHOW_QUOTA_GROUP
759
760         echo "    delete the big file of $FSIZE G..."
761         $RUNAS rm -f $TESTFILE 
762
763         $SHOW_QUOTA_USER
764         $SHOW_QUOTA_GROUP
765
766         echo "    write the big file of 2 G..."
767         $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((2 * GB / blkzise)) || \
768                 error "(usr) write 2 G file failure, but expect success" 
769
770         echo "    delete the big file of 2 G..."
771         $RUNAS rm -f $TESTFILE 
772
773         RC=$?
774
775         # clear the flage
776         debugrestore
777
778         # make qd_count 64 bit
779         sysctl -w lustre.fail_loc=0
780
781         set_blk_tunesz $BTUNE_SZ
782         set_blk_unitsz $BUNIT_SZ
783
784         wait_delete_completed
785
786         return $RC
787 }
788 run_test 10 "run for fixing bug10707(32bit) ==========="
789
790 test_11() {
791        wait_delete_completed
792
793        #prepare the test
794        block_limit=`(echo 0; df -t lustre -P | awk '{print $(NF - 4)}') | tail -n 1`
795        echo $block_limit
796        orig_dbr=`cat /proc/sys/vm/dirty_background_ratio`
797        orig_dec=`cat /proc/sys/vm/dirty_expire_centisecs`
798        orig_dr=`cat /proc/sys/vm/dirty_ratio`
799        orig_dwc=`cat /proc/sys/vm/dirty_writeback_centisecs`
800        echo 1  > /proc/sys/vm/dirty_background_ratio
801        echo 30 > /proc/sys/vm/dirty_expire_centisecs
802        echo 1  > /proc/sys/vm/dirty_ratio
803        echo 50 > /proc/sys/vm/dirty_writeback_centisecs
804        TESTDIR="$DIR/$tdir"
805        local RV=0
806
807        #do the test
808        local SECS=0
809        local REPS=3
810        [ "$SLOW" = no ] && REPS=1
811        local sleep=20
812        local i=1
813        while [ $i -le $REPS ]; do
814            echo "test: cycle($i of $REPS) start at $(date)"
815            mkdir -p $TESTDIR && chmod 777 $TESTDIR
816            echo -n "    create a file for uid "
817            for j in `seq 1 30`; do
818                echo -n "$j "
819                # 30MB per dd for a total of 900MB (if space even permits)
820                runas -u $j dd if=/dev/zero of=$TESTDIR/$tfile  bs=$blksize count=15 > /dev/null 2>&1 &
821            done
822            echo ""
823            PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
824            LAST_USED=0
825            while [ $PROCS -gt 0 ]; do 
826              sleep 20
827              SECS=$((SECS + sleep))
828              PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
829              USED=$(du -s $TESTDIR | awk '{print $1}')
830              PCT=$(($USED * 100 / $block_limit))
831              echo "${i}/${REPS} ${PCT}% p${PROCS} t${SECS}  "
832              if [ $USED -le $LAST_USED ]; then
833                  kill -9 $(ps -ef | grep "dd if /dev/zero of $TESTDIR" | grep -v grep | awk '{ print $2 }')
834                  i=$REPS
835                  RV=2
836                  break
837              fi
838              LAST_USED=$USED
839            done
840            echo "    removing the test files..."
841            rm -f $TESTDIR/$tfile
842            echo "cycle $i done at $(date)"
843            i=$[$i+1]
844        done
845        echo "Test took $SECS sec"
846
847        #clean
848        echo $orig_dbr > /proc/sys/vm/dirty_background_ratio
849        echo $orig_dec > /proc/sys/vm/dirty_expire_centisecs
850        echo $orig_dr  > /proc/sys/vm/dirty_ratio
851        echo $orig_dwc > /proc/sys/vm/dirty_writeback_centisecs
852        if [ $RV -ne 0 ]; then
853            error "Nothing was written for $SECS sec ... aborting"
854        fi
855        return $RV
856 }
857 run_test 11 "run for fixing bug10912 ==========="
858
859
860 # test a deadlock between quota and journal b=11693
861 test_12() {
862         mkdir -p $DIR/$tdir
863         chmod 0777 $DIR/$tdir
864
865         [ "$(grep $DIR2 /proc/mounts)" ] || mount_client $DIR2 || \
866                 { skip "Need lustre mounted on $MOUNT2 " && retutn 0; }
867
868         LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
869         TESTFILE="$DIR/$tdir/$tfile-0"
870         TESTFILE2="$DIR2/$tdir/$tfile-1"
871         
872         echo "   User quota (limit: $LIMIT kbytes)"
873         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
874
875         $LFS setstripe $TESTFILE -i 0 -c 1 
876         chown $TSTUSR.$TSTUSR $TESTFILE
877         $LFS setstripe $TESTFILE2 -i 0 -c 1
878         chown $TSTUSR2.$TSTUSR2 $TESTFILE2
879
880         #define OBD_FAIL_OST_HOLD_WRITE_RPC      0x21f
881         sysctl -w lustre.fail_loc=0x0000021f        
882
883         echo "   step1: write out of block quota ..."
884         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT*2)) & 
885         DDPID=$!
886         sleep 5
887         $RUNAS2 dd if=/dev/zero of=$TESTFILE2 bs=$BLK_SZ count=102400 & 
888         DDPID1=$!
889
890         echo  "   step2: testing ......"
891         count=0
892         while [ true ]; do
893             if [ -z `ps -ef | awk '$2 == '${DDPID1}' { print $8 }'` ]; then break; fi
894             count=$[count+1]
895             if [ $count -gt 64 ]; then
896                 sysctl -w lustre.fail_loc=0
897                 error "dd should be finished!"
898             fi
899             sleep 1
900         done    
901         echo "(dd_pid=$DDPID1, time=$count)successful"
902
903         #Recover fail_loc and dd will finish soon
904         sysctl -w lustre.fail_loc=0
905
906         echo  "   step3: testing ......"
907         count=0
908         while [ true ]; do
909             if [ -z `ps -ef | awk '$2 == '${DDPID}' { print $8 }'` ]; then break; fi
910             count=$[count+1]
911             if [ $count -gt 100 ]; then
912                 error "dd should be finished!"
913             fi
914             sleep 1
915         done    
916         echo "(dd_pid=$DDPID, time=$count)successful"
917
918         rm -f $TESTFILE $TESTFILE2
919         
920         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
921 }
922 run_test 12 "test a deadlock between quota and journal ==="
923
924 # test multiple clients write block quota b=11693
925 test_13() {
926         # one OST * 10 + (mds + other OSTs)
927         LIMIT=$((BUNIT_SZ * 10 + (BUNIT_SZ * OSTCOUNT)))
928         TESTFILE="$DIR/$tdir/$tfile"
929         mkdir -p $DIR/$tdir
930
931         echo "   User quota (limit: $LIMIT kbytes)"
932         $LFS setquota -u $TSTUSR 0 $LIMIT 0 0 $DIR
933         $SHOW_QUOTA_USER
934         
935         $LFS setstripe $TESTFILE -i 0 -c 1
936         chown $TSTUSR.$TSTUSR $TESTFILE
937         $LFS setstripe $TESTFILE.2 -i 0 -c 1
938         chown $TSTUSR.$TSTUSR $TESTFILE.2
939
940         echo "   step1: write out of block quota ..."
941         # one bunit will give mds
942         $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$[($LIMIT - $BUNIT_SZ) / 2] & 
943         DDPID=$!
944         $RUNAS dd if=/dev/zero of=$TESTFILE.2 bs=$BLK_SZ count=$[($LIMIT - $BUNIT_SZ) / 2] & 
945         DDPID1=$!
946
947         echo  "   step2: testing ......"
948         count=0
949         while [ true ]; do
950             if [ -z `ps -ef | awk '$2 == '${DDPID}' { print $8 }'` ]; then break; fi
951             count=$[count+1]
952             if [ $count -gt 64 ]; then
953                 error "dd should be finished!"
954             fi
955             sleep 1
956         done    
957         echo "(dd_pid=$DDPID, time=$count)successful"
958
959         count=0
960         while [ true ]; do
961             if [ -z `ps -ef | awk '$2 == '${DDPID1}' { print $8 }'` ]; then break; fi
962             count=$[count+1]
963             if [ $count -gt 64 ]; then
964                 error "dd should be finished!"
965             fi
966             sleep 1
967         done    
968         echo "(dd_pid=$DDPID1, time=$count)successful"
969
970         sync; sleep 5; sync;
971
972         echo  "   step3: checking ......"
973         fz=`stat -c %s $TESTFILE`
974         fz2=`stat -c %s $TESTFILE.2`
975         $SHOW_QUOTA_USER
976         [ $((fz + fz2)) -lt $((BUNIT_SZ * BLK_SZ * 10)) ] && \
977                 error "files too small $fz + $fz2 < $((BUNIT_SZ * BLK_SZ * 10))"
978
979         rm -f $TESTFILE $TESTFILE.2
980         
981         $LFS setquota -u $TSTUSR 0 0 0 0 $DIR           # clear user limit
982 }
983 run_test 13 "test multiple clients write block quota ==="
984
985 check_if_quota_zero(){
986         line=`$LFS quota -$1 $2 $DIR | wc -l`
987         for i in `seq 3 $line`; do
988             if [ $i -eq 3 ]; then
989                 field="3 4 6 7"
990             else
991                 field="3 5"
992             fi
993             for j in $field; do
994                 tmp=`$LFS quota -$1 $2 $DIR | sed -n ${i}p | 
995                      awk  '{print $'"$j"'}'`
996                 [ -n "$tmp" ] && [ $tmp -ne 0 ] && $LFS quota -$1 $2 $DIR && \
997                     error "quota on $2 isn't clean"
998             done
999         done
1000         echo "pass check_if_quota_zero"
1001 }
1002
1003 pre_test_14 () {
1004         # reboot the lustre
1005         cd $T_PWD; sh llmountcleanup.sh || error "llmountcleanup failed"
1006         sh llmount.sh
1007         pre_test
1008         run_test 0 "reboot lustre"
1009 }
1010
1011 pre_test_14 
1012
1013 test_14a() {    # was test_14 b=12223 -- setting quota on root
1014         TESTFILE="$DIR/$tdir/$tfile"
1015         mkdir -p $DIR/$tdir
1016
1017         # out of root's file and block quota
1018         $LFS setquota -u root 10 10 10 10 $DIR
1019         createmany -m ${TESTFILE} 20 || \
1020             error "unexpected: user(root) create files failly!"
1021         dd if=/dev/zero of=$TESTFILE bs=4k count=4096 || \
1022             error "unexpected: user(root) write files failly!"
1023         chmod 666 $TESTFILE
1024         $RUNAS dd if=/dev/zero of=${TESTFILE} seek=4096 bs=4k count=4096 && \
1025             error "unexpected: user(quota_usr) write a file successfully!"      
1026
1027         # trigger the llog
1028         chmod 777 $DIR
1029         for i in `seq 1 10`; do $RUNAS touch ${TESTFILE}a_$i; done 
1030         for i in `seq 1 10`; do $RUNAS rm -f ${TESTFILE}a_$i; done 
1031
1032         # do the check
1033         dmesg | tail | grep "\-122" |grep llog_obd_origin_add && error "err -122 not found in dmesg" 
1034         $LFS setquota -u root 0 0 0 0 $DIR
1035         #check_if_quota_zero u root
1036
1037         # clean 
1038         unlinkmany ${TESTFILE} 15
1039         rm -f $TESTFILE
1040 }
1041 run_test 14a "test setting quota on root ==="
1042
1043 # turn off quota
1044 test_99()
1045 {
1046         $LFS quotaoff $DIR
1047         return 0
1048 }
1049 run_test 99 "Quota off ==============================="
1050
1051
1052 log "cleanup: ======================================================"
1053 cd $ORIG_PWD
1054 post_test
1055 check_and_cleanup_lustre
1056 echo '=========================== finished ==============================='
1057 [ -f "$QUOTALOG" ] && cat $QUOTALOG && grep -q FAIL $QUOTALOG && exit 1 || true
1058 echo "$0: completed"