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