Whamcloud - gitweb
LU-2284 quota: debug patch for test_7d
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # Run test by setting NOSETUP=true when ltest has setup env for us
7 set -e
8
9 SRCDIR=`dirname $0`
10 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
11
12 ONLY=${ONLY:-"$*"}
13 ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT"
14 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
15
16 [ "$ALWAYS_EXCEPT$EXCEPT" ] &&
17         echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
18
19 TMP=${TMP:-/tmp}
20
21 ORIG_PWD=${PWD}
22 TSTID=${TSTID:-60000}
23 TSTID2=${TSTID2:-60001}
24 TSTUSR=${TSTUSR:-"quota_usr"}
25 TSTUSR2=${TSTUSR2:-"quota_2usr"}
26 BLK_SZ=1024
27 MAX_DQ_TIME=604800
28 MAX_IQ_TIME=604800
29
30 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
31 . $LUSTRE/tests/test-framework.sh
32 init_test_env $@
33 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
34 init_logging
35 DIRECTIO=${DIRECTIO:-$LUSTRE/tests/directio}
36
37 [ $MDSCOUNT -gt 1 ] && skip "CMD case" && exit 0
38
39 require_dsh_mds || exit 0
40 require_dsh_ost || exit 0
41
42 # XXX Once we drop the interoperability with old server (< 2.3.50), the
43 #     sanity-quota-old.sh should be removed.
44 if [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.50) ]; then
45         exec $LUSTRE/tests/sanity-quota-old.sh
46 fi
47
48 # if e2fsprogs support quota feature?
49 if [ $(facet_fstype $SINGLEMDS) == ldiskfs ] && \
50         ! $DEBUGFS -c -R supported_features | grep -q 'quota'; then
51         skip "e2fsprogs doesn't support quota" && exit 0
52 fi
53
54 [ "$SLOW" = "no" ] && EXCEPT_SLOW="9 18 21"
55
56 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
57
58 [ "$QUOTALOG" ] && rm -f $QUOTALOG || true
59
60 DIR=${DIR:-$MOUNT}
61 DIR2=${DIR2:-$MOUNT2}
62
63 QUOTA_AUTO_OLD=$QUOTA_AUTO
64 export QUOTA_AUTO=0
65
66 check_and_setup_lustre
67
68 LOVNAME=`lctl get_param -n llite.*.lov.common_name | tail -n 1`
69 OSTCOUNT=`lctl get_param -n lov.$LOVNAME.numobd`
70
71 SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
72 SHOW_QUOTA_USERID="$LFS quota -v -u $TSTID $DIR"
73 SHOW_QUOTA_USER2="$LFS quota -v -u $TSTUSR2 $DIR"
74 SHOW_QUOTA_GROUP="$LFS quota -v -g $TSTUSR $DIR"
75 SHOW_QUOTA_GROUPID="$LFS quota -v -g $TSTID $DIR"
76 SHOW_QUOTA_GROUP2="$LFS quota -v -g $TSTUSR2 $DIR"
77 SHOW_QUOTA_INFO_USER="$LFS quota -t -u $DIR"
78 SHOW_QUOTA_INFO_GROUP="$LFS quota -t -g $DIR"
79
80 build_test_filter
81
82 lustre_fail() {
83         local fail_node=$1
84         local fail_loc=$2
85         local fail_val=${3:-0}
86
87         if [ $fail_node == "mds" ] || [ $fail_node == "mds_ost" ]; then
88                 do_facet $SINGLEMDS "lctl set_param fail_val=$fail_val"
89                 do_facet $SINGLEMDS "lctl set_param fail_loc=$fail_loc"
90         fi
91
92         if [ $fail_node == "ost" ] || [ $fail_node == "mds_ost" ]; then
93                 for num in `seq $OSTCOUNT`; do
94                         do_facet ost$num "lctl set_param fail_val=$fail_val"
95                         do_facet ost$num "lctl set_param fail_loc=$fail_loc"
96                 done
97         fi
98 }
99
100 RUNAS="runas -u $TSTID -g $TSTID"
101 RUNAS2="runas -u $TSTID2 -g $TSTID2"
102 DD="dd if=/dev/zero bs=1M"
103
104 FAIL_ON_ERROR=false
105
106 check_runas_id_ret $TSTUSR $TSTUSR $RUNAS ||
107         error "Please create user $TSTUSR($TSTID) and group $TSTUSR($TSTID)"
108 check_runas_id_ret $TSTUSR2 $TSTUSR2 $RUNAS2 ||
109         error "Please create user $TSTUSR2($TSTID2) and group $TSTUSR2($TSTID2)"
110
111 # clear quota limits for a user or a group
112 # usage: resetquota -u username
113 #        resetquota -g groupname
114
115 resetquota() {
116         [ "$#" != 2 ] && error "resetquota: wrong number of arguments: $#"
117         [ "$1" != "-u" -a "$1" != "-g" ] &&
118                 error "resetquota: wrong specifier $1 passed"
119
120         $LFS setquota "$1" "$2" -b 0 -B 0 -i 0 -I 0 $MOUNT ||
121                 error "clear quota for [type:$1 name:$2] failed"
122         # give a chance to slave to release space
123         sleep 1
124 }
125
126 quota_scan() {
127         local LOCAL_UG=$1
128         local LOCAL_ID=$2
129
130         if [ "$LOCAL_UG" == "a" -o "$LOCAL_UG" == "u" ]; then
131                 $LFS quota -v -u $LOCAL_ID $DIR
132                 log "Files for user ($LOCAL_ID):"
133                 ($LFS find -user $LOCAL_ID $DIR | head -n 4 |
134                         xargs stat 2>/dev/null)
135         fi
136
137         if [ "$LOCAL_UG" == "a" -o "$LOCAL_UG" == "g" ]; then
138                 $LFS quota -v -u $LOCAL_ID $DIR
139                 log "Files for group ($LOCAL_ID):"
140                 ($LFS find -group $LOCAL_ID $DIR | head -n 4 |
141                         xargs stat 2>/dev/null)
142         fi
143 }
144
145 quota_error() {
146         quota_scan $1 $2
147         shift 2
148         error "$*"
149 }
150
151 quota_log() {
152         quota_scan $1 $2
153         shift 2
154         log "$*"
155 }
156
157 # get quota for a user or a group
158 # usage: getquota -u|-g <username>|<groupname> global|<obd_uuid> \
159 #                 bhardlimit|bsoftlimit|bgrace|ihardlimit|isoftlimit|igrace
160 #
161 getquota() {
162         local spec
163         local uuid
164
165         [ "$#" != 4 ] && error "getquota: wrong number of arguments: $#"
166         [ "$1" != "-u" -a "$1" != "-g" ] &&
167                 error "getquota: wrong u/g specifier $1 passed"
168
169         uuid="$3"
170
171         case "$4" in
172                 curspace)   spec=1;;
173                 bsoftlimit) spec=2;;
174                 bhardlimit) spec=3;;
175                 bgrace)     spec=4;;
176                 curinodes)  spec=5;;
177                 isoftlimit) spec=6;;
178                 ihardlimit) spec=7;;
179                 igrace)     spec=8;;
180                 *)          error "unknown quota parameter $4";;
181         esac
182
183         [ "$uuid" = "global" ] && uuid=$DIR
184
185         $LFS quota -v "$1" "$2" $DIR |
186                 awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") \
187                 { if (NF == 1) { getline } else { num++ } ; print $num;} }' \
188                 | tr -d "*"
189 }
190
191 # set mdt quota type
192 # usage: set_mdt_qtype ug|u|g|none
193 set_mdt_qtype() {
194         local qtype=$1
195         local varsvc=${SINGLEMDS}_svc
196         do_facet mgs $LCTL conf_param $FSNAME.quota.mdt=$qtype
197         if $(facet_up $SINGLEMDS); then
198                 wait_update_facet $SINGLEMDS "$LCTL get_param -n \
199                         osd-$FSTYPE.${!varsvc}.quota_slave.enabled" "$qtype" ||
200                                 return 1
201         fi
202         return 0
203 }
204
205 # set ost quota type
206 # usage: set_ost_quota_type ug|u|g|none
207 set_ost_qtype() {
208         local qtype=$1
209         local varsvc
210         local osts=$(get_facets OST)
211         do_facet mgs $LCTL conf_param $FSNAME.quota.ost=$qtype
212         # we have to make sure each OST received config changes
213         for ost in ${osts//,/ }; do
214                 varsvc=${ost}_svc
215                 if $(facet_up $ost); then
216                         wait_update_facet $ost "$LCTL get_param -n \
217                                 osd-$FSTYPE.${!varsvc}.quota_slave.enabled" \
218                                         "$qtype" || return 1
219                 fi
220         done
221         return 0
222 }
223
224 wait_reintegration() {
225         local ntype=$1
226         local qtype=$2
227         local result="glb[1],slv[1],reint[0]"
228         local varsvc
229
230         if [ $ntype == "mdt" ]; then
231                 varsvc=${SINGLEMDS}_svc
232                 if $(facet_up $SINGLEMDS); then
233                         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
234                         osd-$FSTYPE.${!varsvc}.quota_slave.info |
235                         grep "$qtype" | awk '{ print \\\$3 }'" "$result" ||
236                                 return 1
237                 fi
238         else
239                 local osts=$(get_facets OST)
240                 for ost in ${osts//,/ }; do
241                         varsvc=${ost}_svc
242                         if $(facet_up $ost); then
243                                 wait_update_facet $ost "$LCTL get_param -n \
244                                 osd-$FSTYPE.${!varsvc}.quota_slave.info |
245                                 grep "$qtype" | awk '{ print \\\$3 }'" \
246                                         "$result" || return 1
247                         fi
248                 done
249         fi
250         return 0
251 }
252
253 wait_mdt_reint() {
254         local qtype=$1
255
256         if [ $qtype == "u" ] || [ $qtype == "ug" ]; then
257                 wait_reintegration "mdt" "user" || return 1
258         fi
259
260         if [ $qtype == "g" ] || [ $qtype == "ug" ]; then
261                 wait_reintegration "mdt" "group" || return 1
262         fi
263         return 0
264 }
265
266 wait_ost_reint() {
267         local qtype=$1
268
269         if [ $qtype == "u" ] || [ $qtype == "ug" ]; then
270                 wait_reintegration "ost" "user" || return 1
271         fi
272
273         if [ $qtype == "g" ] || [ $qtype == "ug" ]; then
274                 wait_reintegration "ost" "group" || return 1
275         fi
276         return 0
277 }
278
279 setup_quota_test() {
280         rm -rf $DIR/$tdir
281         wait_delete_completed
282         echo "Creating test directory"
283         mkdir -p $DIR/$tdir
284         chmod 077 $DIR/$tdir
285         # always clear fail_loc in case of fail_loc isn't cleared
286         # properly when previous test failed
287         lustre_fail mds_ost 0
288 }
289
290 cleanup_quota_test() {
291         trap 0
292         echo "Delete files..."
293         rm -rf $DIR/$tdir
294         echo "Wait for unlink objects finished..."
295         wait_delete_completed
296         sync_all_data || true
297 }
298
299 quota_show_check() {
300         local bf=$1
301         local ug=$2
302         local qid=$3
303         local usage
304
305         $LFS quota -v -$ug $qid $DIR
306
307         if [ "$bf" == "a" -o "$bf" == "b" ]; then
308                 usage=$(getquota -$ug $qid global curspace)
309                 if [ -z $usage ]; then
310                         quota_error $ug $qid \
311                                 "Query block quota failed ($ug:$qid)."
312                 else
313                         [ $usage -ne 0 ] && quota_log $ug $qid \
314                                 "Block quota isn't 0 ($ug:$qid:$usage)."
315                 fi
316         fi
317
318         if [ "$bf" == "a" -o "$bf" == "f" ]; then
319                 usage=$(getquota -$ug $qid global curinodes)
320                 if [ -z $usage ]; then
321                         quota_error $ug $qid \
322                                 "Query file quota failed ($ug:$qid)."
323                 else
324                         [ $usage -ne 0 ] && quota_log $ug $qid \
325                                 "File quota isn't 0 ($ug:$qid:$usage)."
326                 fi
327         fi
328 }
329
330 # enable quota debug
331 quota_init() {
332         do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
333 }
334 quota_init
335
336 test_quota_performance() {
337         local TESTFILE="$DIR/$tdir/$tfile-0"
338         local size=$1 # in MB
339         local stime=$(date +%s)
340         $RUNAS $DD of=$TESTFILE count=$size conv=fsync ||
341                 quota_error u $TSTUSR "write failure"
342         local etime=$(date +%s)
343         delta=$((etime - stime))
344         if [ $delta -gt 0 ]; then
345             rate=$((size * 1024 / delta))
346             [ $rate -gt 1024 ] ||
347                 error "SLOW IO for $TSTUSR (user): $rate KB/sec"
348         fi
349         rm -f $TESTFILE
350 }
351
352 # test basic quota performance b=21696
353 test_0() {
354         local MB=100 # 100M
355         [ "$SLOW" = "no" ] && MB=10
356
357         local free_space=$(lfs df | grep "filesystem summary" | \
358                                 awk '{print $5}')
359         [ $free_space -le $((MB * 1024)) ] &&
360                 skip "not enough space ${free_space} KB, " \
361                         "required $((MB * 1024)) KB" && return
362         setup_quota_test
363         trap cleanup_quota_test EXIT
364
365         set_ost_qtype "none" || error "disable ost quota failed"
366         test_quota_performance $MB
367
368         set_ost_qtype "ug" || error "enable ost quota failed"
369         $LFS setquota -u $TSTUSR -b 0 -B 10G -i 0 -I 0 $DIR ||
370                 error "set quota failed"
371         test_quota_performance $MB
372
373         cleanup_quota_test
374         resetquota -u $TSTUSR
375 }
376 run_test 0 "Test basic quota performance"
377
378 # test block hardlimit
379 test_1() {
380         local LIMIT=10  # 10M
381         local TESTFILE="$DIR/$tdir/$tfile-0"
382
383         setup_quota_test
384         trap cleanup_quota_test EXIT
385
386         # enable ost quota
387         set_ost_qtype "ug" || "enable ost quota failed"
388
389         # test for user
390         log "User quota (block hardlimit:$LIMIT MB)"
391         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
392                 error "set user quota failed"
393
394         # make sure the system is clean
395         local USED=$(getquota -u $TSTUSR global curspace)
396         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
397
398         $LFS setstripe $TESTFILE -c 1
399         chown $TSTUSR.$TSTUSR $TESTFILE
400
401         log "Write..."
402         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) ||
403                 quota_error u $TSTUSR "user write failure, but expect success"
404         log "Write out of block quota ..."
405         # this time maybe cache write,  ignore it's failure
406         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) seek=$((LIMIT/2)) || true
407         # flush cache, ensure noquota flag is set on client
408         cancel_lru_locks osc
409         $RUNAS $DD of=$TESTFILE count=1 seek=$LIMIT &&
410                 quota_error u $TSTUSR "user write success, but expect EDQUOT"
411
412         rm -f $TESTFILE
413         wait_delete_completed
414         sync_all_data || true
415         USED=$(getquota -u $TSTUSR global curspace)
416         [ $USED -ne 0 ] && quota_error u $TSTUSR \
417                 "user quota isn't released after deletion"
418         resetquota -u $TSTUSR
419
420         # test for group
421         log "--------------------------------------"
422         log "Group quota (block hardlimit:$LIMIT MB)"
423         $LFS setquota -g $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
424                 error "set group quota failed"
425
426         TESTFILE="$DIR/$tdir/$tfile-1"
427         # make sure the system is clean
428         USED=$(getquota -g $TSTUSR global curspace)
429         [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0"
430
431         $LFS setstripe $TESTFILE -c 1
432         chown $TSTUSR.$TSTUSR $TESTFILE
433
434         log "Write ..."
435         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) ||
436                 quota_error g $TSTUSR "group write failure, but expect success"
437         log "Write out of block quota ..."
438         # this time maybe cache write, ignore it's failure
439         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) seek=$((LIMIT/2)) || true
440         cancel_lru_locks osc
441         $RUNAS $DD of=$TESTFILE count=10 seek=$LIMIT &&
442                 quota_error g $TSTUSR "group write success, but expect EDQUOT"
443
444         # cleanup
445         cleanup_quota_test
446
447         USED=$(getquota -g $TSTUSR global curspace)
448         [ $USED -ne 0 ] && quota_error g $TSTUSR \
449                 "group quota isn't released after deletion"
450
451         resetquota -g $TSTUSR
452 }
453 run_test 1 "Block hard limit (normal use and out of quota)"
454
455 # test inode hardlimit
456 test_2() {
457         local LIMIT=$((1024 * 1024)) # 1M inodes
458         local TESTFILE="$DIR/$tdir/$tfile-0"
459
460         [ "$SLOW" = "no" ] && LIMIT=1024 # 1k inodes
461
462         local FREE_INODES=$(lfs df -i | grep "filesystem summary" | \
463                                 awk '{print $5}')
464         [ $FREE_INODES -lt $LIMIT ] &&
465                 skip "not enough free inodes $FREE_INODES required $LIMIT" &&
466                 return
467
468         setup_quota_test
469         trap cleanup_quota_test EXIT
470
471         # enable mdt quota
472         set_mdt_qtype "ug" || "enable mdt quota failed"
473
474         # test for user
475         log "User quota (inode hardlimit:$LIMIT files)"
476         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
477                 error "set user quota failed"
478
479         # make sure the system is clean
480         local USED=$(getquota -u $TSTUSR global curinodes)
481         [ $USED -ne 0 ] && error "Used inodes($USED) for user $TSTUSR isn't 0."
482
483         log "Create $LIMIT files ..."
484         $RUNAS createmany -m ${TESTFILE} $LIMIT || \
485                 quota_error u $TSTUSR "user create failure, but expect success"
486         log "Create out of file quota ..."
487         $RUNAS touch ${TESTFILE}_xxx && \
488                 quota_error u $TSTUSR "user create success, but expect EDQUOT"
489
490         # cleanup
491         unlinkmany ${TESTFILE} $LIMIT
492         rm -f ${TESTFILE}_xxx
493         wait_delete_completed
494
495         USED=$(getquota -u $TSTUSR global curinodes)
496         [ $USED -ne 0 ] && quota_error u $TSTUSR \
497                 "user quota isn't released after deletion"
498         resetquota -u $TSTUSR
499
500         # test for group
501         log "--------------------------------------"
502         log "Group quota (inode hardlimit:$LIMIT files)"
503         $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
504                 error "set group quota failed"
505
506         TESTFILE=$DIR/$tdir/$tfile-1
507         # make sure the system is clean
508         USED=$(getquota -g $TSTUSR global curinodes)
509         [ $USED -ne 0 ] && error "Used inodes($USED) for group $TSTUSR isn't 0."
510
511         log "Create $LIMIT files ..."
512         $RUNAS createmany -m ${TESTFILE} $LIMIT ||
513                 quota_error g $TSTUSR "group create failure, but expect success"
514         log "Create out of file quota ..."
515         $RUNAS touch ${TESTFILE}_xxx && \
516                 quota_error g $TSTUSR "group create success, but expect EDQUOT"
517
518         # cleanup
519         unlinkmany ${TESTFILE} $LIMIT
520         rm -f ${TESTFILE}_xxx
521         wait_delete_completed
522
523         USED=$(getquota -g $TSTUSR global curinodes)
524         [ $USED -ne 0 ] && quota_error g $TSTUSR \
525                 "user quota isn't released after deletion"
526
527         cleanup_quota_test
528         resetquota -g $TSTUSR
529 }
530 run_test 2 "File hard limit (normal use and out of quota)"
531
532 test_block_soft() {
533         local TESTFILE=$1
534         local TIMER=$(($2 * 3 / 2))
535         local LIMIT=$3
536         local OFFSET=0
537
538         setup_quota_test
539         trap cleanup_quota_test EXIT
540
541         $LFS setstripe $TESTFILE -c 1 -i 0
542         chown $TSTUSR.$TSTUSR $TESTFILE
543
544         echo "Write up to soft limit"
545         $RUNAS $DD of=$TESTFILE count=$LIMIT ||
546                 quota_error a $TSTUSR "write failure, but expect success"
547         OFFSET=$((LIMIT * 1024))
548         cancel_lru_locks osc
549
550         echo "Write to exceed soft limit"
551         $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET ||
552                 quota_error a $TSTUSR "write failure, but expect success"
553         OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
554         cancel_lru_locks osc
555
556         $SHOW_QUOTA_USER
557         $SHOW_QUOTA_GROUP
558         $SHOW_QUOTA_INFO_USER
559         $SHOW_QUOTA_INFO_GROUP
560
561         echo "Write before timer goes off"
562         $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET ||
563                 quota_error a $TSTUSR "write failure, but expect success"
564         OFFSET=$((OFFSET + 1024))
565         cancel_lru_locks osc
566
567         echo "Sleep $TIMER seconds ..."
568         sleep $TIMER
569
570         $SHOW_QUOTA_USER
571         $SHOW_QUOTA_GROUP
572         $SHOW_QUOTA_INFO_USER
573         $SHOW_QUOTA_INFO_GROUP
574
575         echo "Write after timer goes off"
576         # maybe cache write, ignore.
577         $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET || true
578         OFFSET=$((OFFSET + 1024))
579         cancel_lru_locks osc
580         $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET &&
581                 quota_error a $TSTUSR "write success, but expect EDQUOT"
582
583         $SHOW_QUOTA_USER
584         $SHOW_QUOTA_GROUP
585         $SHOW_QUOTA_INFO_USER
586         $SHOW_QUOTA_INFO_GROUP
587
588         echo "Unlink file to stop timer"
589         rm -f $TESTFILE
590         wait_delete_completed
591         sync_all_data || true
592
593         $SHOW_QUOTA_USER
594         $SHOW_QUOTA_GROUP
595         $SHOW_QUOTA_INFO_USER
596         $SHOW_QUOTA_INFO_GROUP
597
598         $LFS setstripe $TESTFILE -c 1 -i 0
599         chown $TSTUSR.$TSTUSR $TESTFILE
600
601         echo "Write ..."
602         $RUNAS $DD of=$TESTFILE count=$LIMIT ||
603                 quota_error a $TSTUSR "write failure, but expect success"
604         # cleanup
605         cleanup_quota_test
606 }
607
608 # block soft limit
609 test_3() {
610         local LIMIT=1  # 1MB
611         local GRACE=10 # 10s
612         local TESTFILE=$DIR/$tdir/$tfile-0
613
614         set_ost_qtype "ug" || error "enable ost quota failed"
615
616         echo "User quota (soft limit:$LIMIT MB  grace:$GRACE seconds)"
617         # make sure the system is clean
618         local USED=$(getquota -u $TSTUSR global curspace)
619         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
620
621         $LFS setquota -t -u --block-grace $GRACE --inode-grace \
622                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
623         $LFS setquota -u $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
624                 error "set user quota failed"
625
626         test_block_soft $TESTFILE $GRACE $LIMIT
627         resetquota -u $TSTUSR
628
629         echo "Group quota (soft limit:$LIMIT MB  grace:$GRACE seconds)"
630         TESTFILE=$DIR/$tdir/$tfile-1
631         # make sure the system is clean
632         USED=$(getquota -g $TSTUSR global curspace)
633         [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0."
634
635         $LFS setquota -t -g --block-grace $GRACE --inode-grace \
636                 $MAX_IQ_TIME $DIR || error "set group grace time failed"
637         $LFS setquota -g $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
638                 error "set group quota failed"
639
640         test_block_soft $TESTFILE $GRACE $LIMIT
641         resetquota -g $TSTUSR
642
643         # cleanup
644         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
645                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
646         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
647                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
648 }
649 run_test 3 "Block soft limit (start timer, timer goes off, stop timer)"
650
651 test_file_soft() {
652         local TESTFILE=$1
653         local LIMIT=$2
654         local TIMER=$(($3 * 3 / 2))
655
656         setup_quota_test
657         trap cleanup_quota_test EXIT
658
659         echo "Create files to exceed soft limit"
660         $RUNAS createmany -m ${TESTFILE}_ $((LIMIT + 1)) ||
661                 quota_error a $TSTUSR "create failure, but expect success"
662         sync; sleep 1; sync
663
664         echo "Create file before timer goes off"
665         $RUNAS touch ${TESTFILE}_before ||
666                 quota_error a $TSTUSR "failed create before timer expired," \
667                         "but expect success"
668         sync; sleep 1; sync
669
670         echo "Sleep $TIMER seconds ..."
671         sleep $TIMER
672
673         $SHOW_QUOTA_USER
674         $SHOW_QUOTA_GROUP
675         $SHOW_QUOTA_INFO_USER
676         $SHOW_QUOTA_INFO_GROUP
677
678         echo "Create file after timer goes off"
679         # There is a window that space is accounted in the quota usage but
680         # hasn't been decreased from the pending write, if we acquire quota
681         # in this window, we'll acquire more than we needed.
682         $RUNAS touch ${TESTFILE}_after_1 ${TESTFILE}_after_2 || true
683         sync; sleep 1; sync
684         $RUNAS touch ${TESTFILE}_after_3 &&
685                 quota_error a $TSTUSR "create after timer expired," \
686                         "but expect EDQUOT"
687         sync; sleep 1; sync
688
689         $SHOW_QUOTA_USER
690         $SHOW_QUOTA_GROUP
691         $SHOW_QUOTA_INFO_USER
692         $SHOW_QUOTA_INFO_GROUP
693
694         echo "Unlink files to stop timer"
695         find $(dirname $TESTFILE) -name "$(basename ${TESTFILE})*" | xargs rm -f
696         wait_delete_completed
697
698         echo "Create file"
699         $RUNAS touch ${TESTFILE}_xxx ||
700                 quota_error a $TSTUSR "touch after timer stop failure," \
701                         "but expect success"
702         sync; sleep 1; sync
703
704         # cleanup
705         cleanup_quota_test
706 }
707
708 # file soft limit
709 test_4a() {
710         local LIMIT=10 # inodes
711         local TESTFILE=$DIR/$tdir/$tfile-0
712         local GRACE=5
713
714         set_mdt_qtype "ug" || error "enable mdt quota failed"
715
716         echo "User quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
717         # make sure the system is clean
718         local USED=$(getquota -u $TSTUSR global curinodes)
719         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
720
721         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
722                 $GRACE $DIR || error "set user grace time failed"
723         $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
724                 error "set user quota failed"
725
726         test_file_soft $TESTFILE $LIMIT $GRACE
727         resetquota -u $TSTUSR
728
729         echo "Group quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
730         # make sure the system is clean
731         USED=$(getquota -g $TSTUSR global curinodes)
732         [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0."
733
734         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
735                 $GRACE $DIR || error "set group grace time failed"
736         $LFS setquota -g $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
737                 error "set group quota failed"
738         TESTFILE=$DIR/$tdir/$tfile-1
739
740         test_file_soft $TESTFILE $LIMIT $GRACE
741         resetquota -g $TSTUSR
742
743         # cleanup
744         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
745                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
746         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
747                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
748 }
749 run_test 4a "File soft limit (start timer, timer goes off, stop timer)"
750
751 test_4b() {
752         local GR_STR1="1w3d"
753         local GR_STR2="1000s"
754         local GR_STR3="5s"
755         local GR_STR4="1w2d3h4m5s"
756         local GR_STR5="5c"
757         local GR_STR6="1111111111111111"
758
759         wait_delete_completed
760
761         # test of valid grace strings handling
762         echo "Valid grace strings test"
763         $LFS setquota -t -u --block-grace $GR_STR1 --inode-grace \
764                 $GR_STR2 $DIR || error "set user grace time failed"
765         $LFS quota -u -t $DIR | grep "Block grace time: $GR_STR1"
766         $LFS setquota -t -g --block-grace $GR_STR3 --inode-grace \
767                 $GR_STR4 $DIR || error "set group grace time quota failed"
768         $LFS quota -g -t $DIR | grep "Inode grace time: $GR_STR4"
769
770         # test of invalid grace strings handling
771         echo "  Invalid grace strings test"
772         ! $LFS setquota -t -u --block-grace $GR_STR4 --inode-grace $GR_STR5 $DIR
773         ! $LFS setquota -t -g --block-grace $GR_STR4 --inode-grace $GR_STR6 $DIR
774
775         # cleanup
776         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
777                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
778         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
779                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
780 }
781 run_test 4b "Grace time strings handling"
782
783 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
784 test_5() {
785         local BLIMIT=10 # 10M
786         local ILIMIT=10 # 10 inodes
787
788         setup_quota_test
789         trap cleanup_quota_test EXIT
790
791         set_mdt_qtype "ug" || error "enable mdt quota failed"
792         set_ost_qtype "ug" || error "enable ost quota failed"
793
794         echo "Set quota limit (0 ${BLIMIT}M 0 $ILIMIT) for $TSTUSR.$TSTUSR"
795         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
796                 error "set user quota failed"
797         $LFS setquota -g $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
798                 error "set group quota failed"
799
800         # make sure the system is clean
801         local USED=$(getquota -u $TSTUSR global curinodes)
802         [ $USED -ne 0 ] && error "Used inode($USED) for user $TSTUSR isn't 0."
803         USED=$(getquota -g $TSTUSR global curinodes)
804         [ $USED -ne 0 ] && error "Used inode($USED) for group $TSTUSR isn't 0."
805         USED=$(getquota -u $TSTUSR global curspace)
806         [ $USED -ne 0 ] && error "Used block($USED) for user $TSTUSR isn't 0."
807         USED=$(getquota -g $TSTUSR global curspace)
808         [ $USED -ne 0 ] && error "Used block($USED) for group $TSTUSR isn't 0."
809
810         echo "Create more than $ILIMIT files and more than $BLIMIT MB ..."
811         createmany -m $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
812                 error "create failure, expect success"
813         $DD of=$DIR/$tdir/$tfile-0_1 count=$((BLIMIT+1)) ||
814                 error "write failure, expect success"
815
816         echo "Chown files to $TSTUSR.$TSTUSR ..."
817         for i in `seq 0 $ILIMIT`; do
818                 chown $TSTUSR.$TSTUSR $DIR/$tdir/$tfile-0_$i ||
819                         quota_error a $TSTUSR "chown failure, expect success"
820         done
821
822         # cleanup
823         unlinkmany $DIR/$tdir/$tfile-0_ $((ILIMIT + 1))
824         cleanup_quota_test
825
826         resetquota -u $TSTUSR
827         resetquota -g $TSTUSR
828 }
829 run_test 5 "Chown & chgrp successfully even out of block/file quota"
830
831 # test dropping acquire request on master
832 test_6() {
833         local LIMIT=3 # 3M
834
835         setup_quota_test
836         trap cleanup_quota_test EXIT
837
838         # make sure the system is clean
839         local USED=$(getquota -u $TSTUSR global curspace)
840         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
841
842         # make sure no granted quota on ost
843         set_ost_qtype "ug" || error "enable ost quota failed"
844         resetquota -u $TSTUSR
845
846         # create file for $TSTUSR
847         local TESTFILE=$DIR/$tdir/$tfile-$TSTUSR
848         $LFS setstripe $TESTFILE -c 1 -i 0
849         chown $TSTUSR.$TSTUSR $TESTFILE
850
851         # create file for $TSTUSR2
852         local TESTFILE2=$DIR/$tdir/$tfile-$TSTUSR2
853         $LFS setstripe $TESTFILE2 -c 1 -i 0
854         chown $TSTUSR2.$TSTUSR2 $TESTFILE2
855
856         # cache per-ID lock for $TSTUSR on slave
857         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
858                 error "set quota failed"
859         $RUNAS $DD of=$TESTFILE count=1 ||
860                 error "write $TESTFILE failure, expect success"
861         $RUNAS2 $DD of=$TESTFILE2 count=1 ||
862                 error "write $TESTFILE2 failure, expect success"
863         sync; sync
864         sync_all_data || true
865
866         #define QUOTA_DQACQ 601
867         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC 0x513
868         lustre_fail mds 0x513 601
869
870         # write to un-enforced ID ($TSTUSR2) should succeed
871         $RUNAS2 $DD of=$TESTFILE2 count=$LIMIT seek=1 oflag=sync conv=notrunc ||
872                 error "write failure, expect success"
873
874         # write to enforced ID ($TSTUSR) in background, exceeding limit
875         # to make sure DQACQ is sent
876         $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync conv=notrunc &
877         DDPID=$!
878
879         # watchdog timer uses a factor of 2
880         echo "Sleep for $((TIMEOUT * 2 + 1)) seconds ..."
881         sleep $((TIMEOUT * 2 + 1))
882
883         # write should be blocked and never finished
884         if ! ps -p $DDPID  > /dev/null 2>&1; then
885                 lustre_fail mds 0 0
886                 error "write finished incorrectly!"
887         fi
888
889         lustre_fail mds 0 0
890
891         # no watchdog is triggered
892         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
893         watchdog=$(awk '/sanity-quota test 6/ {start = 1;}
894                        /Service thread pid/ && /was inactive/ {
895                                if (start) {
896                                        print;
897                                }
898                        }' $TMP/lustre-log-${TESTNAME}.log)
899         [ -z "$watchdog" ] || error "$watchdog"
900
901         rm -f $TMP/lustre-log-${TESTNAME}.log
902
903         # write should continue & succeed
904         local count=0
905         while [ true ]; do
906                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
907                 if [ $count -ge 120 ]; then
908                         quota_error u $TSTUSR "dd not finished in $count secs"
909                 fi
910                 count=$((count + 1))
911                 [ $((count % 10)) -eq 0 ] && echo "Waiting $count secs"
912                 sleep 1
913         done
914
915         cleanup_quota_test
916         resetquota -u $TSTUSR
917 }
918 run_test 6 "Test dropping acquire request on master"
919
920 # quota reintegration (global index)
921 test_7a() {
922         local TESTFILE=$DIR/$tdir/$tfile
923         local LIMIT=20 # 20M
924
925         [ "$SLOW" = "no" ] && LIMIT=5
926
927         setup_quota_test
928         trap cleanup_quota_test EXIT
929
930         # make sure the system is clean
931         local USED=$(getquota -u $TSTUSR global curspace)
932         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
933
934         # make sure no granted quota on ost1
935         set_ost_qtype "ug" || error "enable ost quota failed"
936         resetquota -u $TSTUSR
937         set_ost_qtype "none" || error "disable ost quota failed"
938
939         local OSTUUID=$(ostuuid_from_index 0)
940         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
941         [ $USED -ne 0 ] && error "limit($USED) on $OSTUUID for user" \
942                 "$TSTUSR isn't 0."
943
944         # create test file
945         $LFS setstripe $TESTFILE -c 1 -i 0
946         chown $TSTUSR.$TSTUSR $TESTFILE
947
948         echo "Stop ost1..."
949         stop ost1
950
951         echo "Enable quota & set quota limit for $TSTUSR"
952         set_ost_qtype "ug" || error "enable ost quota failed"
953         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
954                 error "set quota failed"
955
956         echo "Start ost1..."
957         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
958
959         wait_ost_reint "ug" || error "reintegration failed"
960
961         # hardlimit should have been fetched by slave during global
962         # reintegration, write will exceed quota
963         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
964                 quota_error u $TSTUSR "write success, but expect EDQUOT"
965
966         rm -f $TESTFILE
967         wait_delete_completed
968         sync_all_data || true
969         sleep 3
970
971         echo "Stop ost1..."
972         stop ost1
973
974         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
975                 error "clear quota failed"
976
977         echo "Start ost1..."
978         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
979
980         wait_ost_reint "ug" || error "reintegration failed"
981
982         # hardlimit should be cleared on slave during reintegration
983         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync ||
984                 quota_error u $TSTUSR "write error, but expect success"
985
986         cleanup_quota_test
987         resetquota -u $TSTUSR
988 }
989 run_test 7a "Quota reintegration (global index)"
990
991 # quota reintegration (slave index)
992 test_7b() {
993         local LIMIT="100G"
994         local TESTFILE=$DIR/$tdir/$tfile
995
996         setup_quota_test
997         trap cleanup_quota_test EXIT
998
999         # make sure the system is clean
1000         local USED=$(getquota -u $TSTUSR global curspace)
1001         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1002
1003         # make sure no granted quota on ost1
1004         set_ost_qtype "ug" || error "enable ost quota failed"
1005         resetquota -u $TSTUSR
1006         set_ost_qtype "none" || error "disable ost quota failed"
1007
1008         local OSTUUID=$(ostuuid_from_index 0)
1009         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
1010         [ $USED -ne 0 ] && error "limit($USED) on $OSTUUID for user" \
1011                 "$TSTUSR isn't 0."
1012
1013         # create test file
1014         $LFS setstripe $TESTFILE -c 1 -i 0
1015         chown $TSTUSR.$TSTUSR $TESTFILE
1016
1017         # consume some space to make sure the granted space will not
1018         # be released during reconciliation
1019         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
1020                 error "consume space failure, expect success"
1021
1022         # define OBD_FAIL_QUOTA_EDQUOT 0xa02
1023         lustre_fail mds 0xa02
1024
1025         set_ost_qtype "ug" || error "enable ost quota failed"
1026         $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
1027                 error "set quota failed"
1028
1029         # ignore the write error
1030         $RUNAS $DD of=$TESTFILE count=1 seek=1 oflag=sync conv=notrunc
1031
1032         local old_used=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
1033
1034         lustre_fail mds 0
1035
1036         echo "Restart ost to trigger reintegration..."
1037         stop ost1
1038         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
1039
1040         wait_ost_reint "ug" || error "reintegration failed"
1041
1042         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
1043         [ $USED -gt $old_used ] || error "limit on $OSTUUID $USED <= $old_used"
1044
1045         cleanup_quota_test
1046         resetquota -u $TSTUSR
1047         $SHOW_QUOTA_USER
1048 }
1049 run_test 7b "Quota reintegration (slave index)"
1050
1051 # quota reintegration (restart mds during reintegration)
1052 test_7c() {
1053         local LIMIT=20 # 20M
1054         local TESTFILE=$DIR/$tdir/$tfile
1055
1056         [ "$SLOW" = "no" ] && LIMIT=5
1057
1058         setup_quota_test
1059         trap cleanup_quota_test EXIT
1060
1061         # make sure the system is clean
1062         local USED=$(getquota -u $TSTUSR global curspace)
1063         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1064
1065         set_ost_qtype "none" || error "disable ost quota failed"
1066         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
1067                 error "set quota failed"
1068
1069         # define OBD_FAIL_QUOTA_DELAY_REINT 0xa03
1070         lustre_fail ost 0xa03
1071
1072         # enable ost quota to trigger reintegration
1073         set_ost_qtype "ug" || error "enable ost quota failed"
1074
1075         echo "Stop mds..."
1076         stop mds1
1077
1078         lustre_fail ost 0
1079
1080         echo "Start mds..."
1081         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
1082
1083         wait_ost_reint "ug" || error "reintegration failed"
1084
1085         # hardlimit should have been fetched by slave during global
1086         # reintegration, write will exceed quota
1087         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
1088                 quota_error u $TSTUSR "write success, but expect EDQUOT"
1089
1090         cleanup_quota_test
1091         resetquota -u $TSTUSR
1092 }
1093 run_test 7c "Quota reintegration (restart mds during reintegration)"
1094
1095 # Quota reintegration (Transfer index in multiple bulks)
1096 test_7d(){
1097         local TESTFILE=$DIR/$tdir/$tfile
1098         local TESTFILE1="$DIR/$tdir/$tfile"-1
1099         local limit=20 #20M
1100
1101         setup_quota_test
1102         trap cleanup_quota_test EXIT
1103
1104         set_ost_qtype "none" || error "disable ost quota failed"
1105         # LU-2284. Enable trace for debug log.
1106         do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+trace"
1107         $LFS setquota -u $TSTUSR -B ${limit}M $DIR ||
1108                 error "set quota for $TSTUSR failed"
1109         $LFS setquota -u $TSTUSR2 -B ${limit}M $DIR ||
1110                 error "set quota for $TSTUSR2 failed"
1111         do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-trace"
1112
1113         #define OBD_FAIL_OBD_IDX_READ_BREAK 0x608
1114         lustre_fail mds 0x608 0
1115
1116         # enable quota to tirgger reintegration
1117         set_ost_qtype "u" || error "enable ost quota failed"
1118         wait_ost_reint "u" || error "reintegration failed"
1119
1120         lustre_fail mds 0
1121
1122         # hardlimit should have been fetched by slave during global
1123         # reintegration, write will exceed quota
1124         $RUNAS $DD of=$TESTFILE count=$((limit + 1)) oflag=sync &&
1125                 quota_error u $TSTUSR "$TSTUSR write success, expect EDQUOT"
1126
1127         $RUNAS2 $DD of=$TESTFILE1 count=$((limit + 1)) oflag=sync &&
1128                 quota_error u $TSTUSR2 "$TSTUSR2 write success, expect EDQUOT"
1129
1130         cleanup_quota_test
1131         resetquota -u $TSTUSR
1132         resetquota -u $TSTUSR2
1133 }
1134 run_test 7d "Quota reintegration (Transfer index in multiple bulks)"
1135
1136 # run dbench with quota enabled
1137 test_8() {
1138         local BLK_LIMIT="100g" #100G
1139         local FILE_LIMIT=1000000
1140
1141         setup_quota_test
1142         trap cleanup_quota_test EXIT
1143
1144         set_mdt_qtype "ug" || error "enable mdt quota failed"
1145         set_ost_qtype "ug" || error "enable ost quota failed"
1146
1147         echo "Set enough high limit for user: $TSTUSR"
1148         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
1149                 error "set user quota failed"
1150         echo "Set enough high limit for group: $TSTUSR"
1151         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
1152                 error "set group quota failed"
1153
1154         local duration=""
1155         [ "$SLOW" = "no" ] && duration=" -t 120"
1156         $RUNAS bash rundbench -D $DIR/$tdir 3 $duration ||
1157                 quota_error a $TSTUSR "dbench failed!"
1158
1159         cleanup_quota_test
1160         resetquota -u $TSTUSR
1161         resetquota -g $TSTUSR
1162 }
1163 run_test 8 "Run dbench with quota enabled"
1164
1165 # this check is just for test_9
1166 OST0_MIN=4900000 #4.67G
1167
1168 check_whether_skip () {
1169         local OST0_SIZE=$($LFS df $DIR | awk '/\[OST:0\]/ {print $4}')
1170         log "OST0_SIZE: $OST0_SIZE  required: $OST0_MIN"
1171         if [ $OST0_SIZE -lt $OST0_MIN ]; then
1172                 echo "WARN: OST0 has less than $OST0_MIN free, skip this test."
1173                 return 0
1174         else
1175                 return 1
1176         fi
1177 }
1178
1179 # run for fixing bug10707, it needs a big room. test for 64bit
1180 test_9() {
1181         local filesize=$((1024 * 1024 * 1024 * 9 / 2)) # 4.5G
1182
1183         check_whether_skip && return 0
1184
1185         setup_quota_test
1186         trap cleanup_quota_test EXIT
1187
1188         set_ost_qtype "ug" || error "enable ost quota failed"
1189
1190         local TESTFILE="$DIR/$tdir/$tfile-0"
1191         local BLK_LIMIT=100G #100G
1192         local FILE_LIMIT=1000000
1193
1194         echo "Set block limit $BLK_LIMIT bytes to $TSTUSR.$TSTUSR"
1195
1196         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
1197                 "for user: $TSTUSR"
1198         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
1199                 error "set user quota failed"
1200
1201         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
1202                 "for group: $TSTUSR"
1203         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
1204                 error "set group quota failed"
1205
1206         quota_show_check a u $TSTUSR
1207         quota_show_check a g $TSTUSR
1208
1209         echo "Create test file"
1210         $LFS setstripe $TESTFILE -c 1 -i 0
1211         chown $TSTUSR.$TSTUSR $TESTFILE
1212
1213         log "Write the big file of 4.5G ..."
1214         $RUNAS $DD of=$TESTFILE count=$filesize ||
1215                 quota_error a $TSTUSR "write 4.5G file failure, expect success"
1216
1217         $SHOW_QUOTA_USER
1218         $SHOW_QUOTA_GROUP
1219
1220         cleanup_quota_test
1221         resetquota -u $TSTUSR
1222         resetquota -g $TSTUSR
1223
1224         $SHOW_QUOTA_USER
1225         $SHOW_QUOTA_GROUP
1226 }
1227 run_test 9 "Block limit larger than 4GB (b10707)"
1228
1229 test_10() {
1230         local TESTFILE=$DIR/$tdir/$tfile
1231
1232         setup_quota_test
1233         trap cleanup_quota_test EXIT
1234
1235         # set limit to root user should fail
1236         $LFS setquota -u root -b 100G -B 500G -i 1K -I 1M $DIR &&
1237                 error "set limit for root user successfully, expect failure"
1238         $LFS setquota -g root -b 1T -B 10T -i 5K -I 100M $DIR &&
1239                 error "set limit for root group successfully, expect failure"
1240
1241         # root user can overrun quota
1242         set_ost_qtype "ug" || "enable ost quota failed"
1243
1244         $LFS setquota -u $TSTUSR -b 0 -B 2M -i 0 -I 0 $DIR ||
1245                 error "set quota failed"
1246         quota_show_check b u $TSTUSR
1247
1248         $LFS setstripe $TESTFILE -c 1
1249         chown $TSTUSR.$TSTUSR $TESTFILE
1250
1251         runas -u 0 -g 0 $DD of=$TESTFILE count=3 oflag=sync ||
1252                 error "write failure, expect success"
1253
1254         cleanup_quota_test
1255         resetquota -u $TSTUSR
1256 }
1257 run_test 10 "Test quota for root user"
1258
1259 test_11() {
1260         local TESTFILE=$DIR/$tdir/$tfile
1261         setup_quota_test
1262         trap cleanup_quota_test EXIT
1263
1264         set_mdt_qtype "ug" || "enable mdt quota failed"
1265         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 1 $DIR ||
1266                 error "set quota failed"
1267
1268         touch "$TESTFILE"-0
1269         touch "$TESTFILE"-1
1270
1271         chown $TSTUSR.$TSTUSR "$TESTFILE"-0
1272         chown $TSTUSR.$TSTUSR "$TESTFILE"-1
1273
1274         $SHOW_QUOTA_USER
1275         local USED=$(getquota -u $TSTUSR global curinodes)
1276         [ $USED -ge 2 ] || error "Used inodes($USED) is less than 2"
1277
1278         cleanup_quota_test
1279         resetquota -u $TSTUSR
1280 }
1281 run_test 11 "Chown/chgrp ignores quota"
1282
1283 test_12() {
1284         [ "$OSTCOUNT" -lt "2" ] && skip "skipping rebalancing test" && return
1285
1286         local blimit=22 # 22M
1287         local blk_cnt=$((blimit - 5))
1288         local TESTFILE0="$DIR/$tdir/$tfile"-0
1289         local TESTFILE1="$DIR/$tdir/$tfile"-1
1290
1291         setup_quota_test
1292         trap cleanup_quota_test EXIT
1293
1294         set_ost_qtype "u" || "enable ost quota failed"
1295         quota_show_check b u $TSTUSR
1296
1297         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $DIR ||
1298                 error "set quota failed"
1299
1300         $LFS setstripe $TESTFILE0 -c 1 -i 0
1301         $LFS setstripe $TESTFILE1 -c 1 -i 1
1302         chown $TSTUSR.$TSTUSR $TESTFILE0
1303         chown $TSTUSR.$TSTUSR $TESTFILE1
1304
1305         echo "Write to ost0..."
1306         $RUNAS $DD of=$TESTFILE0 count=$blk_cnt oflag=sync ||
1307                 quota_error a $TSTUSR "dd failed"
1308
1309         echo "Write to ost1..."
1310         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync &&
1311                 quota_error a $TSTUSR "dd succeed, expect EDQUOT"
1312
1313         echo "Free space from ost0..."
1314         rm -f $TESTFILE0
1315         wait_delete_completed
1316         sync_all_data || true
1317
1318         echo "Write to ost1 after space freed from ost0..."
1319         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync ||
1320                 quota_error a $TSTUSR "rebalancing failed"
1321
1322         cleanup_quota_test
1323         resetquota -u $TSTUSR
1324 }
1325 run_test 12 "Block quota rebalancing"
1326
1327 test_13(){
1328         local TESTFILE=$DIR/$tdir/$tfile
1329         # the name of osp on ost1 name is MDT0000-osp-OST0000
1330         local procf="ldlm.namespaces.*MDT0000-osp-OST0000.lru_size"
1331
1332         setup_quota_test
1333         trap cleanup_quota_test EXIT
1334
1335         set_ost_qtype "u" || "enable ost quota failed"
1336         quota_show_check b u $TSTUSR
1337
1338         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
1339                 error "set quota failed"
1340         $LFS setstripe $TESTFILE -c 1 -i 0
1341         chown $TSTUSR.$TSTUSR $TESTFILE
1342
1343         # clear the locks in cache first
1344         do_facet ost1 $LCTL set_param -n $procf=clear
1345         local nlock=$(do_facet ost1 $LCTL get_param -n $procf)
1346         [ $nlock -eq 0 ] || error "$nlock cached locks"
1347
1348         # write to acquire the per-ID lock
1349         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
1350                 quota_error a $TSTUSR "dd failed"
1351
1352         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
1353         [ $nlock -eq 1 ] || error "lock count($nlock) isn't 1"
1354
1355         # clear quota doesn't trigger per-ID lock cancellation
1356         resetquota -u $TSTUSR
1357         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
1358         [ $nlock -eq 1 ] || error "per-ID lock is lost on quota clear"
1359
1360         # clear the per-ID lock
1361         do_facet ost1 $LCTL set_param -n $procf=clear
1362         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
1363         [ $nlock -eq 0 ] || error "per-ID lock isn't cleared"
1364
1365         # spare quota should be released
1366         local OSTUUID=$(ostuuid_from_index 0)
1367         local limit=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
1368         local space=$(getquota -u $TSTUSR $OSTUUID curspace)
1369         [ $limit -le $space ] ||
1370                 error "spare quota isn't released, limit:$limit, space:$space"
1371
1372         cleanup_quota_test
1373 }
1374 run_test 13 "Cancel per-ID lock in the LRU list"
1375
1376 test_15(){
1377         local LIMIT=$((24 * 1024 * 1024 * 1024 * 1024)) # 24 TB
1378
1379         wait_delete_completed
1380         sync_all_data || true
1381
1382         # test for user
1383         $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
1384                 error "set user quota failed"
1385         local TOTAL_LIMIT=$(getquota -u $TSTUSR global bhardlimit)
1386         [ $TOTAL_LIMIT -eq $LIMIT ] ||
1387                 error "(user) limit:$TOTAL_LIMIT, expect:$LIMIT, failed!"
1388         resetquota -u $TSTUSR
1389
1390         # test for group
1391         $LFS setquota -g $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
1392                 error "set group quota failed"
1393         TOTAL_LIMIT=$(getquota -g $TSTUSR global bhardlimit)
1394         [ $TOTAL_LIMIT -eq $LIMIT ] ||
1395                 error "(group) limits:$TOTAL_LIMIT, expect:$LIMIT, failed!"
1396         resetquota -g $TSTUSR
1397 }
1398 run_test 15 "Set over 4T block quota"
1399
1400 test_17sub() {
1401         local err_code=$1
1402         local BLKS=1    # 1M less than limit
1403         local TESTFILE=$DIR/$tdir/$tfile
1404
1405         setup_quota_test
1406         trap cleanup_quota_test EXIT
1407
1408         # make sure the system is clean
1409         local USED=$(getquota -u $TSTUSR global curspace)
1410         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1411
1412         set_ost_qtype "ug" || error "enable ost quota failed"
1413         # make sure no granted quota on ost
1414         resetquota -u $TSTUSR
1415         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
1416                 error "set quota failed"
1417
1418         quota_show_check b u $TSTUSR
1419
1420         #define OBD_FAIL_QUOTA_RECOVERABLE_ERR 0xa04
1421         lustre_fail mds 0xa04 $err_code
1422
1423         # write in background
1424         $RUNAS $DD of=$TESTFILE count=$BLKS oflag=direct &
1425         local DDPID=$!
1426
1427         sleep 2
1428         # write should be blocked and never finished
1429         if ! ps -p $DDPID  > /dev/null 2>&1; then
1430                 lustre_fail mds 0 0
1431                 quota_error u $TSTUSR "write finished incorrectly!"
1432         fi
1433
1434         lustre_fail mds 0 0
1435
1436         local count=0
1437         local timeout=30
1438         while [ true ]; do
1439                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
1440                 count=$((count+1))
1441                 if [ $count -gt $timeout ]; then
1442                         quota_error u $TSTUSR "dd is not finished!"
1443                 fi
1444                 sleep 1
1445         done
1446
1447         sync; sync_all_data || true
1448
1449         USED=$(getquota -u $TSTUSR global curspace)
1450         [ $USED -ge $(($BLKS * 1024)) ] || quota_error u $TSTUSR \
1451                 "Used space(${USED}K) is less than ${BLKS}M"
1452
1453         cleanup_quota_test
1454         resetquota -u $TSTUSR
1455 }
1456
1457 # DQACQ return recoverable error
1458 test_17() {
1459         echo "DQACQ return -ENOLCK"
1460         #define ENOLCK  37
1461         test_17sub 37 || error "Handle -ENOLCK failed"
1462
1463         echo "DQACQ return -EAGAIN"
1464         #define EAGAIN  11
1465         test_17sub 11 || error "Handle -EAGAIN failed"
1466
1467         echo "DQACQ return -ETIMEDOUT"
1468         #define ETIMEDOUT 110
1469         test_17sub 110 || error "Handle -ETIMEDOUT failed"
1470
1471         echo "DQACQ return -ENOTCONN"
1472         #define ENOTCONN 107
1473         test_17sub 107 || error "Handle -ENOTCONN failed"
1474 }
1475
1476 run_test 17 "DQACQ return recoverable error"
1477
1478 test_18_sub () {
1479         local io_type=$1
1480         local blimit="200m" # 200M
1481         local TESTFILE="$DIR/$tdir/$tfile"
1482
1483         setup_quota_test
1484         trap cleanup_quota_test EXIT
1485
1486         set_ost_qtype "u" || error "enable ost quota failed"
1487         log "User quota (limit: $blimit)"
1488         $LFS setquota -u $TSTUSR -b 0 -B $blimit -i 0 -I 0 $MOUNT ||
1489                 error "set quota failed"
1490         quota_show_check b u $TSTUSR
1491
1492         $LFS setstripe $TESTFILE -i 0 -c 1
1493         chown $TSTUSR.$TSTUSR $TESTFILE
1494
1495         local timeout=$(sysctl -n lustre.timeout)
1496
1497         if [ $io_type = "directio" ]; then
1498                 log "Write 100M (directio) ..."
1499                 $RUNAS $DD of=$TESTFILE count=100 oflag=direct &
1500         else
1501                 log "Write 100M (buffered) ..."
1502                 $RUNAS $DD of=$TESTFILE count=100 &
1503         fi
1504         local DDPID=$!
1505
1506         replay_barrier $SINGLEMDS
1507         log "Fail mds for $((2 * timeout)) seconds"
1508         fail $SINGLEMDS $((2 * timeout))
1509
1510         local count=0
1511         if at_is_enabled; then
1512                 timeout=$(at_max_get mds)
1513         else
1514                 timeout=$(lctl get_param -n timeout)
1515         fi
1516
1517         while [ true ]; do
1518                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
1519                 if [ $((++count % (2 * timeout) )) -eq 0 ]; then
1520                         log "it took $count second"
1521                 fi
1522                 sleep 1
1523         done
1524
1525         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
1526         sync
1527         cancel_lru_locks mdc
1528         cancel_lru_locks osc
1529         $SHOW_QUOTA_USER
1530
1531         local testfile_size=$(stat -c %s $TESTFILE)
1532         if [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] ; then
1533                 quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100)),"
1534                         "got ${testfile_size}. Verifying file failed!"
1535         fi
1536         cleanup_quota_test
1537         resetquota -u $TSTUSR
1538 }
1539
1540 # test when mds does failover, the ost still could work well
1541 # this test shouldn't trigger watchdog b=14840
1542 test_18() {
1543         test_18_sub normal
1544         test_18_sub directio
1545
1546         # check if watchdog is triggered
1547         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
1548         local watchdog=$(awk '/sanity-quota test 18/ {start = 1;}
1549                        /Service thread pid/ && /was inactive/ {
1550                                if (start) {
1551                                        print;
1552                                }
1553                        }' $TMP/lustre-log-${TESTNAME}.log)
1554         [ -z "$watchdog" ] || error "$watchdog"
1555         rm -f $TMP/lustre-log-${TESTNAME}.log
1556 }
1557 run_test 18 "MDS failover while writing, no watchdog triggered (b14840)"
1558
1559 test_19() {
1560         local blimit=5 # 5M
1561         local TESTFILE=$DIR/$tdir/$tfile
1562
1563         setup_quota_test
1564         trap cleanup_quota_test EXIT
1565
1566         set_ost_qtype "ug" || error "enable ost quota failed"
1567
1568         # bind file to a single OST
1569         $LFS setstripe -c 1 $TESTFILE
1570         chown $TSTUSR.$TSTUSR $TESTFILE
1571
1572         echo "Set user quota (limit: "$blimit"M)"
1573         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
1574                 error "set user quota failed"
1575         quota_show_check b u $TSTUSR
1576         echo "Update quota limits"
1577         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
1578                 error "set group quota failed"
1579         quota_show_check b u $TSTUSR
1580
1581         # first wirte might be cached
1582         $RUNAS $DD of=$TESTFILE count=$((blimit + 1))
1583         cancel_lru_locks osc
1584         $SHOW_QUOTA_USER
1585         $RUNAS $DD of=$TESTFILE count=$((blimit + 1)) seek=$((blimit + 1)) &&
1586                 quota_error u $TSTUSR "Write success, expect failure"
1587         $SHOW_QUOTA_USER
1588
1589         cleanup_quota_test
1590         resetquota -u $TSTUSR
1591 }
1592 run_test 19 "Updating admin limits doesn't zero operational limits(b14790)"
1593
1594 test_20() { # b15754
1595         local LSTR=(2g 1t 4k 3m) # limits strings
1596         # limits values
1597         local LVAL=($[2*1024*1024] $[1*1024*1024*1024] $[4*1024] $[3*1024*1024])
1598
1599         resetquota -u $TSTUSR
1600
1601         $LFS setquota -u $TSTUSR --block-softlimit ${LSTR[0]} \
1602                 $MOUNT || error "could not set quota limits"
1603         $LFS setquota -u $TSTUSR --block-hardlimit ${LSTR[1]} \
1604                                 --inode-softlimit ${LSTR[2]} \
1605                                 --inode-hardlimit ${LSTR[3]} \
1606                                 $MOUNT || error "could not set quota limits"
1607
1608         [ "$(getquota -u $TSTUSR global bsoftlimit)" = "${LVAL[0]}" ] ||
1609                 error "bsoftlimit was not set properly"
1610         [ "$(getquota -u $TSTUSR global bhardlimit)" = "${LVAL[1]}" ] ||
1611                 error "bhardlimit was not set properly"
1612         [ "$(getquota -u $TSTUSR global isoftlimit)" = "${LVAL[2]}" ] ||
1613                 error "isoftlimit was not set properly"
1614         [ "$(getquota -u $TSTUSR global ihardlimit)" = "${LVAL[3]}" ] ||
1615                 error "ihardlimit was not set properly"
1616
1617         resetquota -u $TSTUSR
1618 }
1619 run_test 20 "Test if setquota specifiers work properly (b15754)"
1620
1621 test_21_sub() {
1622         local testfile=$1
1623         local blk_number=$2
1624         local seconds=$3
1625
1626         local time=$(($(date +%s) + seconds))
1627         while [ $(date +%s) -lt $time ]; do
1628                 $RUNAS $DD of=$testfile count=$blk_number > /dev/null 2>&1
1629         done
1630 }
1631
1632 # run for fixing bug16053, setquota shouldn't fail when writing and
1633 # deleting are happening
1634 test_21() {
1635         local TESTFILE="$DIR/$tdir/$tfile"
1636         local BLIMIT=10 # 10G
1637         local ILIMIT=1000000
1638
1639         setup_quota_test
1640         trap cleanup_quota_test EXIT
1641
1642         set_ost_qtype "ug" || error "Enable ost quota failed"
1643
1644         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for user: $TSTUSR"
1645         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}G -i 0 -I $ILIMIT $MOUNT ||
1646                 error "set user quota failed"
1647         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for group: $TSTUSR"
1648         $LFS setquota -g $TSTUSR -b 0 -B $BLIMIT -i 0 -I $ILIMIT $MOUNT ||
1649                 error "set group quota failed"
1650
1651         # repeat writing on a 1M file
1652         test_21_sub ${TESTFILE}_1 1 30 &
1653         local DDPID1=$!
1654         # repeat writing on a 128M file
1655         test_21_sub ${TESTFILE}_2 128 30 &
1656         local DDPID2=$!
1657
1658         local time=$(($(date +%s) + 30))
1659         local i=1
1660         while [ $(date +%s) -lt $time ]; do
1661                 log "Set quota for $i times"
1662                 $LFS setquota -u $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
1663                         -I $((ILIMIT + i)) $MOUNT ||
1664                                 error "Set user quota failed"
1665                 $LFS setquota -g $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
1666                         -I $((ILIMIT + i)) $MOUNT ||
1667                                 error "Set group quota failed"
1668                 i=$((i+1))
1669                 sleep 1
1670         done
1671
1672         local count=0
1673         while [ true ]; do
1674                 if ! ps -p ${DDPID1} > /dev/null 2>&1; then break; fi
1675                 count=$((count+1))
1676                 if [ $count -gt 60 ]; then
1677                         quota_error a $TSTUSR "dd should be finished!"
1678                 fi
1679                 sleep 1
1680         done
1681         echo "(dd_pid=$DDPID1, time=$count)successful"
1682
1683         count=0
1684         while [ true ]; do
1685                 if ! ps -p ${DDPID2} > /dev/null 2>&1; then break; fi
1686                 count=$((count+1))
1687                 if [ $count -gt 60 ]; then
1688                         quota_error a $TSTUSR "dd should be finished!"
1689                 fi
1690                 sleep 1
1691         done
1692         echo "(dd_pid=$DDPID2, time=$count)successful"
1693
1694         cleanup_quota_test
1695         resetquota -u $TSTUSR
1696         resetquota -g $TSTUSR
1697 }
1698 run_test 21 "Setquota while writing & deleting (b16053)"
1699
1700 # enable/disable quota enforcement permanently
1701 test_22() {
1702         echo "Set both mdt & ost quota type as ug"
1703         set_mdt_qtype "ug" || error "enable mdt quota failed"
1704         set_ost_qtype "ug" || error "enable ost quota failed"
1705
1706         echo "Restart..."
1707         stopall
1708         mount
1709         setupall
1710
1711         echo "Verify if quota is enabled"
1712         local qtype=$(mdt_quota_type)
1713         [ $qtype != "ug" ] && error "mdt quota setting is lost"
1714         qtype=$(ost_quota_type)
1715         [ $qtype != "ug" ] && error "ost quota setting is lost"
1716
1717         echo "Set both mdt & ost quota type as none"
1718         set_mdt_qtype "none" || error "disable mdt quota failed"
1719         set_ost_qtype "none" || error "disable ost quota failed"
1720
1721         echo "Restart..."
1722         stopall
1723         mount
1724         setupall
1725
1726         echo "Verify if quota is disabled"
1727         qtype=$(mdt_quota_type)
1728         [ $qtype != "none" ] && error "mdt quota setting is lost"
1729         qtype=$(ost_quota_type)
1730         [ $qtype != "none" ] && error "ost quota setting is lost"
1731
1732         quota_init
1733 }
1734 run_test 22 "enable/disable quota by 'lctl conf_param'"
1735
1736 test_23_sub() {
1737         local TESTFILE="$DIR/$tdir/$tfile"
1738         local LIMIT=$1
1739
1740         setup_quota_test
1741         trap cleanup_quota_test EXIT
1742
1743         set_ost_qtype "ug" || error "Enable ost quota failed"
1744
1745         # test for user
1746         log "User quota (limit: $LIMIT MB)"
1747         $LFS setquota -u $TSTUSR -b 0 -B "$LIMIT"M -i 0 -I 0 $DIR ||
1748                 error "set quota failed"
1749         quota_show_check b u $TSTUSR
1750
1751         $LFS setstripe $TESTFILE -c 1 -i 0
1752         chown $TSTUSR.$TSTUSR $TESTFILE
1753
1754         log "Step1: trigger EDQUOT with O_DIRECT"
1755         log "Write half of file"
1756         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) oflag=direct ||
1757                 quota_error u $TSTUSR "(1) Write failure, expect success." \
1758                         "limit=$LIMIT"
1759         log "Write out of block quota ..."
1760         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2 + 1)) seek=$((LIMIT/2)) \
1761                 oflag=direct conv=notrunc &&
1762                 quota_error u $TSTUSR "(2) Write success, expect EDQUOT." \
1763                         "limit=$LIMIT"
1764         log "Step1: done"
1765
1766         log "Step2: rewrite should succeed"
1767         $RUNAS $DD of=$TESTFILE count=1 oflag=direct conv=notrunc||
1768                 quota_error u $TSTUSR "(3) Write failure, expect success." \
1769                         "limit=$LIMIT"
1770         log "Step2: done"
1771
1772         cleanup_quota_test
1773
1774         local OST0_UUID=$(ostuuid_from_index 0)
1775         local OST0_QUOTA_USED=$(getquota -u $TSTUSR $OST0_UUID curspace)
1776         [ $OST0_QUOTA_USED -ne 0 ] &&
1777                 ($SHOW_QUOTA_USER; \
1778                 quota_error u $TSTUSR "quota isn't released")
1779         $SHOW_QUOTA_USER
1780         resetquota -u $TSTUSR
1781 }
1782
1783 test_23() {
1784         local OST0_MIN=$((6 * 1024)) # 6MB, extra space for meta blocks.
1785         check_whether_skip && return 0
1786         log "run for 4MB test file"
1787         test_23_sub 4
1788
1789         OST0_MIN=$((60 * 1024)) # 60MB, extra space for meta blocks.
1790         check_whether_skip && return 0
1791         log "run for 40MB test file"
1792         test_23_sub 40
1793 }
1794 run_test 23 "Quota should be honored with directIO (b16125)"
1795
1796 test_24() {
1797         local blimit=5 # 5M
1798         local TESTFILE="$DIR/$tdir/$tfile"
1799
1800         setup_quota_test
1801         trap cleanup_quota_test EXIT
1802
1803         set_ost_qtype "ug" || error "enable ost quota failed"
1804
1805         # bind file to a single OST
1806         $LFS setstripe -c 1 $TESTFILE
1807         chown $TSTUSR.$TSTUSR $TESTFILE
1808
1809         echo "Set user quota (limit: "$blimit"M)"
1810         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
1811                 error "set quota failed"
1812
1813         # overrun quota by root user
1814         runas -u 0 -g 0 $DD of=$TESTFILE count=$((blimit + 1)) ||
1815                 error "write failure, expect success"
1816         cancel_lru_locks osc
1817         sync_all_data || true
1818
1819         $SHOW_QUOTA_USER | grep '*' || error "no matching *"
1820
1821         cleanup_quota_test
1822         resetquota -u $TSTUSR
1823 }
1824 run_test 24 "lfs draws an asterix when limit is reached (b16646)"
1825
1826 test_27a() { # b19612
1827         $LFS quota $TSTUSR $DIR &&
1828                 error "lfs succeeded with no type, but should have failed"
1829         $LFS setquota $TSTUSR $DIR &&
1830                 error "lfs succeeded with no type, but should have failed"
1831         return 0
1832 }
1833 run_test 27a "lfs quota/setquota should handle wrong arguments (b19612)"
1834
1835 test_27b() { # b20200
1836         $LFS setquota -u $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
1837                 error "lfs setquota failed with uid argument"
1838         $LFS setquota -g $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
1839                 error "lfs stequota failed with gid argument"
1840         $SHOW_QUOTA_USERID || error "lfs quota failed with uid argument"
1841         $SHOW_QUOTA_GROUPID || error "lfs quota failed with gid argument"
1842         resetquota -u $TSTUSR
1843         resetquota -g $TSTUSR
1844         return 0
1845 }
1846 run_test 27b "lfs quota/setquota should handle user/group ID (b20200)"
1847
1848 test_30() {
1849         local output
1850         local LIMIT=4 # 4MB
1851         local TESTFILE="$DIR/$tdir/$tfile"
1852         local GRACE=10
1853
1854         setup_quota_test
1855         trap cleanup_quota_test EXIT
1856
1857         set_ost_qtype "u" || error "enable ost quota failed"
1858
1859         $LFS setstripe $TESTFILE -i 0 -c 1
1860         chown $TSTUSR.$TSTUSR $TESTFILE
1861
1862         $LFS setquota -t -u --block-grace $GRACE --inode-grace \
1863                 $MAX_IQ_TIME $DIR || error "set grace time failed"
1864         $LFS setquota -u $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
1865                 error "set quota failed"
1866         $RUNAS $DD of=$TESTFILE count=$((LIMIT * 2)) || true
1867         cancel_lru_locks osc
1868         sleep $GRACE
1869         $LFS setquota -u $TSTUSR -B 0 $DIR || error "clear quota failed"
1870         # over-quota flag has not yet settled since we do not trigger async
1871         # events based on grace time period expiration
1872         $SHOW_QUOTA_USER
1873         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=1 || true
1874         cancel_lru_locks osc
1875         # now over-quota flag should be settled and further writes should fail
1876         $SHOW_QUOTA_USER
1877         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=1 &&
1878                 error "grace times were reset"
1879         # cleanup
1880         cleanup_quota_test
1881         resetquota -u $TSTUSR
1882         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1883                 $MAX_IQ_TIME $DIR || error "restore grace time failed"
1884 }
1885 run_test 30 "Hard limit updates should not reset grace times"
1886
1887 # basic usage tracking for user & group
1888 test_33() {
1889         local INODES=10 # 10 files
1890         local BLK_CNT=2 # of 2M each
1891         local TOTAL_BLKS=$((INODES * BLK_CNT * 1024))
1892
1893         setup_quota_test
1894         trap cleanup_quota_test EXIT
1895
1896         # make sure the system is clean
1897         local USED=$(getquota -u $TSTID global curspace)
1898         [ $USED -ne 0 ] &&
1899                 error "Used space ($USED) for user $TSTID isn't 0."
1900         USED=$(getquota -g $TSTID global curspace)
1901         [ $USED -ne 0 ] &&
1902                 error "Used space ($USED) for group $TSTID isn't 0."
1903
1904         echo "Write files..."
1905         for i in `seq 0 $INODES`; do
1906                 $RUNAS $DD of=$DIR/$tdir/$tfile-$i count=$BLK_CNT 2>/dev/null ||
1907                         error "write failed"
1908                 echo "Iteration $i/$INODES completed"
1909         done
1910         cancel_lru_locks osc
1911         sync; sync_all_data || true
1912
1913         echo "Verify disk usage after write"
1914         USED=$(getquota -u $TSTID global curspace)
1915         [ $USED -lt $TOTAL_BLKS ] &&
1916                 error "Used space for user $TSTID:$USED, expected:$TOTAL_BLKS"
1917         USED=$(getquota -g $TSTID global curspace)
1918         [ $USED -lt $TOTAL_BLKS ] &&
1919                 error "Used space for group $TSTID:$USED, expected:$TOTAL_BLKS"
1920
1921         echo "Verify inode usage after write"
1922         USED=$(getquota -u $TSTID global curinodes)
1923         [ $USED -lt $INODES ] &&
1924                 error "Used inode for user $TSTID is $USED, expected $INODES"
1925         USED=$(getquota -g $TSTID global curinodes)
1926         [ $USED -lt $INODES ] &&
1927                 error "Used inode for group $TSTID is $USED, expected $INODES"
1928
1929         cleanup_quota_test
1930
1931         echo "Verify disk usage after delete"
1932         USED=$(getquota -u $TSTID global curspace)
1933         [ $USED -eq 0 ] || error "Used space for user $TSTID isn't 0. $USED"
1934         USED=$(getquota -u $TSTID global curinodes)
1935         [ $USED -eq 0 ] || error "Used inodes for user $TSTID isn't 0. $USED"
1936         USED=$(getquota -g $TSTID global curspace)
1937         [ $USED -eq 0 ] || error "Used space for group $TSTID isn't 0. $USED"
1938         USED=$(getquota -g $TSTID global curinodes)
1939         [ $USED -eq 0 ] || error "Used inodes for group $TSTID isn't 0. $USED"
1940 }
1941 run_test 33 "Basic usage tracking for user & group"
1942
1943 # usage transfer test for user & group
1944 test_34() {
1945         local BLK_CNT=2 # 2MB
1946
1947         setup_quota_test
1948         trap cleanup_quota_test EXIT
1949
1950         # make sure the system is clean
1951         local USED=$(getquota -u $TSTID global curspace)
1952         [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID isn't 0."
1953         USED=$(getquota -g $TSTID global curspace)
1954         [ $USED -ne 0 ] && error "Used space ($USED) for group $TSTID isn't 0."
1955
1956         echo "Write file..."
1957         $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
1958                 error "write failed"
1959         cancel_lru_locks osc
1960         sync; sync_all_data || true
1961
1962         echo "chown the file to user $TSTID"
1963         chown $TSTID $DIR/$tdir/$tfile || error "chown failed"
1964
1965         echo "Wait for setattr on objects finished..."
1966         wait_delete_completed
1967
1968         BLK_CNT=$((BLK_CNT * 1024))
1969
1970         echo "Verify disk usage for user $TSTID"
1971         USED=$(getquota -u $TSTID global curspace)
1972         [ $USED -lt $BLK_CNT ] &&
1973                 error "Used space for user $TSTID is ${USED}, expected $BLK_CNT"
1974         USED=$(getquota -u $TSTID global curinodes)
1975         [ $USED -ne 1 ] &&
1976                 error "Used inodes for user $TSTID is $USED, expected 1"
1977
1978         echo "chgrp the file to group $TSTID"
1979         chgrp $TSTID $DIR/$tdir/$tfile || error "chgrp failed"
1980
1981         echo "Wait for setattr on objects finished..."
1982         wait_delete_completed
1983
1984         echo "Verify disk usage for group $TSTID"
1985         USED=$(getquota -g $TSTID global curspace)
1986         [ $USED -ge $BLK_CNT ] ||
1987                 error "Used space for group $TSTID is $USED, expected $BLK_CNT"
1988         USED=$(getquota -g $TSTID global curinodes)
1989         [ $USED -eq 1 ] ||
1990                 error "Used inodes for group $TSTID is $USED, expected 1"
1991
1992         cleanup_quota_test
1993 }
1994 run_test 34 "Usage transfer for user & group"
1995
1996 # usage is still accessible across restart
1997 test_35() {
1998         local BLK_CNT=2 # 2 MB
1999
2000         setup_quota_test
2001         trap cleanup_quota_test EXIT
2002
2003         echo "Write file..."
2004         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
2005                 error "write failed"
2006         cancel_lru_locks osc
2007         sync; sync_all_data || true
2008
2009         echo "Save disk usage before restart"
2010         local ORIG_USR_SPACE=$(getquota -u $TSTID global curspace)
2011         [ $ORIG_USR_SPACE -eq 0 ] &&
2012                 error "Used space for user $TSTID is 0, expected ${BLK_CNT}M"
2013         local ORIG_USR_INODES=$(getquota -u $TSTID global curinodes)
2014         [ $ORIG_USR_INODES -eq 0 ] &&
2015                 error "Used inodes for user $TSTID is 0, expected 1"
2016         echo "User $TSTID: ${ORIG_USR_SPACE}KB $ORIG_USR_INODES inodes"
2017         local ORIG_GRP_SPACE=$(getquota -g $TSTID global curspace)
2018         [ $ORIG_GRP_SPACE -eq 0 ] &&
2019                 error "Used space for group $TSTID is 0, expected ${BLK_CNT}M"
2020         local ORIG_GRP_INODES=$(getquota -g $TSTID global curinodes)
2021         [ $ORIG_GRP_INODES -eq 0 ] &&
2022                 error "Used inodes for group $TSTID is 0, expected 1"
2023         echo "Group $TSTID: ${ORIG_GRP_SPACE}KB $ORIG_GRP_INODES inodes"
2024
2025         log "Restart..."
2026         local ORIG_REFORMAT=$REFORMAT
2027         REFORMAT=""
2028         cleanup_and_setup_lustre
2029         REFORMAT=$ORIG_REFORMAT
2030         quota_init
2031
2032         echo "Verify disk usage after restart"
2033         local USED=$(getquota -u $TSTID global curspace)
2034         [ $USED -eq $ORIG_USR_SPACE ] ||
2035                 error "Used space for user $TSTID changed from " \
2036                         "$ORIG_USR_SPACE to $USED"
2037         USED=$(getquota -u $TSTID global curinodes)
2038         [ $USED -eq $ORIG_USR_INODES ] ||
2039                 error "Used inodes for user $TSTID changed from " \
2040                         "$ORIG_USR_INODES to $USED"
2041         USED=$(getquota -g $TSTID global curspace)
2042         [ $USED -eq $ORIG_GRP_SPACE ] ||
2043                 error "Used space for group $TSTID changed from " \
2044                         "$ORIG_GRP_SPACE to $USED"
2045         USED=$(getquota -g $TSTID global curinodes)
2046         [ $USED -eq $ORIG_GRP_INODES ] ||
2047                 error "Used inodes for group $TSTID changed from " \
2048                         "$ORIG_GRP_INODES to $USED"
2049
2050         # check if the vfs_dq_init() is called before writing
2051         echo "Append to the same file..."
2052         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT seek=1 2>/dev/null ||
2053                 error "write failed"
2054         cancel_lru_locks osc
2055         sync; sync_all_data || true
2056
2057         echo "Verify space usage is increased"
2058         USED=$(getquota -u $TSTID global curspace)
2059         [ $USED -gt $ORIG_USR_SPACE ] ||
2060                 error "Used space for user $TSTID isn't increased" \
2061                         "orig:$ORIG_USR_SPACE, now:$USED"
2062         USED=$(getquota -g $TSTID global curspace)
2063         [ $USED -gt $ORIG_GRP_SPACE ] ||
2064                 error "Used space for group $TSTID isn't increased" \
2065                         "orig:$ORIG_GRP_SPACE, now:$USED"
2066
2067         cleanup_quota_test
2068 }
2069 run_test 35 "Usage is still accessible across reboot"
2070
2071 # test migrating old amdin quota files (in Linux quota file format v2) into new
2072 # quota global index (in IAM format)
2073 test_36() {
2074         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] && \
2075                 skip "skipping migration test" && return
2076
2077         # get the mdt0 device name
2078         local mdt0_node=$(facet_active_host $SINGLEMDS)
2079         local mdt0_dev=$(mdsdevname ${SINGLEMDS//mds/})
2080
2081         echo "Reformat..."
2082         formatall
2083
2084         echo "Copy admin quota files into MDT0..."
2085         local mntpt=$(facet_mntpt $SINGLEMDS)
2086         local mdt0_fstype=$(facet_fstype $SINGLEMDS)
2087         local opt
2088         if ! do_node $mdt0_node test -b $mdt0_fstype; then
2089                 opt="-o loop"
2090         fi
2091         echo "$mdt0_node, $mdt0_dev, $mntpt, $opt"
2092         do_node $mdt0_node mount -t $mdt0_fstype $opt $mdt0_dev $mntpt
2093         do_node $mdt0_node mkdir $mntpt/OBJECTS
2094         do_node $mdt0_node cp $LUSTRE/tests/admin_quotafile_v2.usr $mntpt/OBJECTS
2095         do_node $mdt0_node cp $LUSTRE/tests/admin_quotafile_v2.grp $mntpt/OBJECTS
2096         do_node $mdt0_node umount -f $mntpt
2097
2098         echo "Setup all..."
2099         setupall
2100
2101         echo "Verify global limits..."
2102         local id_cnt
2103         local limit
2104
2105         local proc="qmt.*.md-0x0.glb-usr"
2106         id_cnt=$(do_node $mdt0_node $LCTL get_param -n $proc | wc -l)
2107         [ $id_cnt -eq 403 ] || error "Migrate inode user limit failed: $id_cnt"
2108         limit=$(getquota -u 1 global isoftlimit)
2109         [ $limit -eq 1024 ] || error "User inode softlimit: $limit"
2110         limit=$(getquota -u 1 global ihardlimit)
2111         [ $limit -eq 2048 ] || error "User inode hardlimit: $limit"
2112
2113         proc="qmt.*.md-0x0.glb-grp"
2114         id_cnt=$(do_node $mdt0_node $LCTL get_param -n $proc | wc -l)
2115         [ $id_cnt -eq 403 ] || error "Migrate inode group limit failed: $id_cnt"
2116         limit=$(getquota -g 1 global isoftlimit)
2117         [ $limit -eq 1024 ] || error "Group inode softlimit: $limit"
2118         limit=$(getquota -g 1 global ihardlimit)
2119         [ $limit -eq 2048 ] || error "Group inode hardlimit: $limit"
2120
2121         proc=" qmt.*.dt-0x0.glb-usr"
2122         id_cnt=$(do_node $mdt0_node $LCTL get_param -n $proc | wc -l)
2123         [ $id_cnt -eq 403 ] || error "Migrate block user limit failed: $id_cnt"
2124         limit=$(getquota -u 60001 global bsoftlimit)
2125         [ $limit -eq 10485760 ] || error "User block softlimit: $limit"
2126         limit=$(getquota -u 60001 global bhardlimit)
2127         [ $limit -eq 20971520 ] || error "User block hardlimit: $limit"
2128
2129         proc="qmt.*.dt-0x0.glb-grp"
2130         id_cnt=$(do_node $mdt0_node $LCTL get_param -n $proc | wc -l)
2131         [ $id_cnt -eq 403 ] || error "Migrate block user limit failed: $id_cnt"
2132         limit=$(getquota -g 60001 global bsoftlimit)
2133         [ $limit -eq 10485760 ] || error "Group block softlimit: $limit"
2134         limit=$(getquota -g 60001 global bhardlimit)
2135         [ $limit -eq 20971520 ] || error "Group block hardlimit: $limit"
2136
2137         echo "Cleanup..."
2138         formatall
2139         setupall
2140 }
2141 run_test 36 "Migrate old admin files into new global indexes"
2142
2143 quota_fini()
2144 {
2145         do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"
2146 }
2147 quota_fini
2148
2149 cd $ORIG_PWD
2150 complete $SECONDS
2151 check_and_cleanup_lustre
2152 export QUOTA_AUTO=$QUOTA_AUTO_OLD
2153 exit_status