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