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