1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2020 Red Hat, Inc. All Rights Reserved.
#
# FS QA Test No. 603
#
# Test per-type(user, group and project) filesystem quota timers, make sure
# enforcement
#
. ./common/preamble
_begin_fstest auto quick quota
# Override the default cleanup function.
_cleanup()
{
_restore_project_quota
cd /
rm -f $tmp.*
}
# Import common functions.
. ./common/filter
. ./common/quota
init_files()
{
local dir=$1
echo "### Initialize files, and their mode and ownership"
touch $dir/file{1,2} 2>/dev/null
chown $qa_user $dir/file{1,2} 2>/dev/null
chgrp $qa_user $dir/file{1,2} 2>/dev/null
chmod 777 $dir 2>/dev/null
}
cleanup_files()
{
echo "### Remove all files"
rm -f ${1}/file{1,2,3,4,5,6}
}
# When project quota is exceeded, some filesystems return ENOSPC (e.g. XFS),
# some filsystems return EDQUOT(e.g. ext4). The behavior isn't definitized.
# So filter the ENOSPC and EDQUOT output.
filter_enospc_edquot()
{
# The filter is only for project quota
if [ "$1" = "P" ];then
sed -e "s,Disk quota exceeded,EDQUOT|ENOSPC,g" \
-e "s,No space left on device,EDQUOT|ENOSPC,g"
else
cat -
fi
}
test_grace()
{
local type=$1
local dir=$2
local bgrace=$3
local igrace=$4
init_files $dir
echo "--- Test block quota ---"
# Firstly fit below block soft limit
echo "Write 225 blocks..."
su $qa_user -c "$XFS_IO_PROG -c 'pwrite 0 $((225 * $BLOCK_SIZE))' \
-c fsync $dir/file1" 2>&1 >>$seqres.full | \
_filter_xfs_io_error | tee -a $seqres.full
repquota -v -$type $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
# Secondly overcome block soft limit
echo "Rewrite 250 blocks plus 1 byte, over the block softlimit..."
su $qa_user -c "$XFS_IO_PROG -c 'pwrite 0 $((250 * $BLOCK_SIZE + 1))' \
-c fsync $dir/file1" 2>&1 >>$seqres.full | \
_filter_xfs_io_error | tee -a $seqres.full
repquota -v -$type $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
# Reset grace time here, make below grace time test more accurate
setquota -$type $qa_user -T $bgrace $igrace $SCRATCH_MNT 2>/dev/null
# Now sleep enough grace time and check that softlimit got enforced
sleep $((bgrace + 1))
echo "Try to write 1 one more block after grace..."
su $qa_user -c "$XFS_IO_PROG -c 'truncate 0' -c 'pwrite 0 $BLOCK_SIZE' \
$dir/file2" 2>&1 >>$seqres.full | _filter_xfs_io_error | \
filter_enospc_edquot $type | tee -a $seqres.full
repquota -v -$type $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
echo "--- Test inode quota ---"
# And now the softlimit test for inodes
# First reset space limits so that we don't have problems with
# space reservations on XFS
setquota -$type $qa_user 0 0 3 100 $SCRATCH_MNT
echo "Create 2 more files, over the inode softlimit..."
su $qa_user -c "touch $dir/file3 $dir/file4" 2>&1 >>$seqres.full | \
_filter_scratch | tee -a $seqres.full
repquota -v -$type $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
# Reset grace time here, make below grace time test more accurate
setquota -$type $qa_user -T $bgrace $igrace $SCRATCH_MNT 2>/dev/null
# Wait and check grace time enforcement
sleep $((igrace+1))
echo "Try to create one more inode after grace..."
su $qa_user -c "touch $dir/file5" 2>&1 >>$seqres.full | \
filter_enospc_edquot $type | _filter_scratch | \
tee -a $seqres.full
repquota -v -$type $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
cleanup_files $dir
}
# real QA test starts here
_supported_fs generic
_require_scratch
# xfs requires v5 format to support all three quota types at the same time
if [ "$FSTYP" = "xfs" ]; then
_require_scratch_xfs_crc
fi
_require_setquota_project
_require_quota
_require_user
_require_group
_scratch_mkfs >$seqres.full 2>&1
_scratch_enable_pquota
_qmount_option "usrquota,grpquota,prjquota"
_qmount
_require_prjquota $SCRATCH_DEV
BLOCK_SIZE=$(_get_file_block_size $SCRATCH_MNT)
rm -rf $SCRATCH_MNT/t
mkdir $SCRATCH_MNT/t
$XFS_IO_PROG -r -c "chproj 100" -c "chattr +P" $SCRATCH_MNT/t
_create_project_quota $SCRATCH_MNT/t 100 $qa_user
echo "### Set up different grace timers to each type of quota"
UBGRACE=12
UIGRACE=10
GBGRACE=4
GIGRACE=2
PBGRACE=8
PIGRACE=6
setquota -u $qa_user $((250 * $BLOCK_SIZE / 1024)) \
$((1000 * $BLOCK_SIZE / 1024)) 3 100 $SCRATCH_MNT
setquota -u -t $UBGRACE $UIGRACE $SCRATCH_MNT
echo; echo "### Test user quota softlimit and grace time"
test_grace u $SCRATCH_MNT $UBGRACE $UIGRACE
# Reset the user quota space & inode limits, avoid it affect later test
setquota -u $qa_user 0 0 0 0 $SCRATCH_MNT
setquota -g $qa_user $((250 * $BLOCK_SIZE / 1024)) \
$((1000 * $BLOCK_SIZE / 1024)) 3 100 $SCRATCH_MNT
setquota -g -t $GBGRACE $GIGRACE $SCRATCH_MNT
echo; echo "### Test group quota softlimit and grace time"
test_grace g $SCRATCH_MNT $GBGRACE $GIGRACE
# Reset the group quota space & inode limits, avoid it affect later test
setquota -g $qa_user 0 0 0 0 $SCRATCH_MNT
setquota -P $qa_user $((250 * $BLOCK_SIZE / 1024)) \
$((1000 * $BLOCK_SIZE / 1024)) 3 100 $SCRATCH_MNT
setquota -P -t $PBGRACE $PIGRACE $SCRATCH_MNT
echo; echo "### Test project quota softlimit and grace time"
test_grace P $SCRATCH_MNT/t $PBGRACE $PIGRACE
# Reset the project quota space & inode limits
setquota -P $qa_user 0 0 0 0 $SCRATCH_MNT
# success, all done
status=0
exit
|