generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / tests / xfs / 152
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0+
3 #
4 # Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
5 # All Rights Reserved.
6 #
7 # FS QA Test No. 152
8 #
9 # Exercise basic xfs_quota functionality (user/group/project quota)
10 # Use of "sync" mount option here is an attempt to get deterministic
11 # allocator behaviour.
12 #
13 . ./common/preamble
14 _begin_fstest auto quick quota idmapped
15
16 wipe_mounts()
17 {
18         umount "${SCRATCH_MNT}/idmapped" >/dev/null 2>&1
19         _scratch_unmount >/dev/null 2>&1
20 }
21
22 # Override the default cleanup function.
23 _cleanup()
24 {
25         cd /
26         wipe_mounts
27         rm -f $tmp.*
28 }
29
30 # Import common functions.
31 . ./common/filter
32 . ./common/quota
33
34 # real QA test starts here
35 _supported_fs xfs
36 _require_idmapped_mounts
37 _require_test_program "idmapped-mounts/mount-idmapped"
38 _require_scratch
39 _require_xfs_quota
40 _require_user fsgqa
41 _require_user fsgqa2
42 _require_group fsgqa
43 _require_group fsgqa2
44
45 _scratch_mkfs_xfs >>$seqres.full 2>&1
46
47 uqid=`id -u fsgqa`
48 gqid=`id -g fsgqa`
49
50 uqid2=`id -u fsgqa2`
51 gqid2=`id -g fsgqa2`
52
53 pqid=10
54 cat >$tmp.projects <<EOF
55 $pqid:$SCRATCH_MNT
56 EOF
57
58 cat >$tmp.projid <<EOF
59 root:0
60 fsgqa:$pqid
61 EOF
62
63 create_files_unmapped()
64 {
65         local bs=$1
66         local inum=$2
67
68         echo "Using type=$type id=$id" >> $seqres.full
69
70         for ((i=0; i<$((inum-1)); i++)); do
71                 _file_as_id $SCRATCH_MNT/unmapped/inode$i $id $type 1024 0
72         done
73
74         _file_as_id $SCRATCH_MNT/unmapped/block $id $type $bs 1
75 }
76
77 create_files_idmapped()
78 {
79         local bs=$1
80         local inum=$2
81
82         echo "Using type=$type id=$id2" >> $seqres.full
83
84         for ((i=0; i<$((inum-1)); i++)); do
85                 _file_as_id $SCRATCH_MNT/idmapped/inode$i $id2 $type 1024 0
86         done
87
88         _file_as_id $SCRATCH_MNT/idmapped/block $id2 $type $bs 1
89 }
90
91 clean_files()
92 {
93         rm -rf $SCRATCH_MNT/unmapped 2>/dev/null
94         rm -rf $SCRATCH_MNT/idmapped 2>/dev/null
95         rm -rf $tmp.quot 2>/dev/null
96         rm -rf $tmp.quota 2>/dev/null
97 }
98
99 filter_quot()
100 {
101         _filter_quota | grep -v "root \|\#0 " \
102                 | sed -e '/#[0-9]*/s/#[0-9]*/#ID/g'
103 }
104
105 filter_report()
106 {
107         _filter_quota | grep -v "^root \|^\#0 " \
108                 | sed -e '/^#[0-9]*/s/^#[0-9]*/#ID/g'
109 }
110
111 filter_quota()
112 {
113         _filter_quota | sed -e "/Disk quotas for/s/([0-9]*)/(ID)/g" \
114                             -e "/Disk quotas for/s/#[0-9]*/#ID/g"
115 }
116
117 filter_state()
118 {
119         _filter_quota | sed -e "s/Inode: #[0-9]* (0 blocks, 0 extents)/Inode: #[INO] (0 blocks, 0 extents)/g" \
120                             -e "s/Inode: #[0-9]* ([0-9]* blocks, [0-9]* extents)/Inode: #[INO] (X blocks, Y extents)/g" \
121                             -e "/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/ [0-9][0-9]:[0-9][0-9]:[0-9][0-9]//g" \
122                             -e '/max warnings:/d'
123 }
124
125 test_quot()
126 {
127         local opt="$*"
128
129         echo "checking quot command (type=$type)"
130         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
131                         -c "quot -$type $opt -bi" $SCRATCH_MNT | filter_quot
132 }
133
134 test_report()
135 {
136         local opt="$*"
137
138         echo "checking report command (type=$type)"
139         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
140                         -c "report -$type $opt -bi" \
141                         $SCRATCH_MNT | filter_report
142 }
143
144 test_quota()
145 {
146         local opt="$*"
147
148         echo "checking quota command (type=$type)"
149         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
150                         -c "quota -$type $opt -bi $id" \
151                         $SCRATCH_MNT | filter_quota
152 }
153
154 test_limit()
155 {
156         local bs=$1
157         local bh=$2
158         local is=$3
159         local ih=$4
160
161         echo "checking limit command (type=$type, bsoft=$bs, bhard=$bh, isoft=$is, ihard=$ih)"
162         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
163                         -c "limit -$type bsoft=$bs bhard=$bh fsgqa" \
164                         -c "limit -$type isoft=$is ihard=$ih fsgqa" \
165                         $SCRATCH_MNT
166
167         # let the timer day transition happen
168         sleep 2
169 }
170
171 test_timer()
172 {
173         echo "checking timer command (type=$type)"
174         # set 3days+1h for time won't become 2days soon
175         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
176                         -c "timer -$type -bi 73h" \
177                         $SCRATCH_MNT | _filter_scratch
178 }
179
180 test_disable()
181 {
182         echo "checking disable command (type=$type)"
183         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
184                         -c "disable -$type -v" \
185                         $SCRATCH_MNT | filter_state
186 }
187
188 test_enable()
189 {
190         echo "checking enable command (type=$type)"
191         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
192                         -c "enable -$type -v" $SCRATCH_MNT | filter_state
193 }
194
195 test_off()
196 {
197         echo "checking off command (type=$type)"
198         _scratch_unmount
199         _qmount_option ""
200         _qmount
201 }
202
203 test_remove()
204 {
205         echo "checking remove command (type=$type)"
206         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
207                         -c "remove -$type -v" \
208                         $SCRATCH_MNT | _filter_scratch
209 }
210
211 test_state()
212 {
213         echo "checking state command (type=$type)"
214         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
215                         -c "state -$type" $SCRATCH_MNT | filter_state
216 }
217
218 test_dump()
219 {
220         echo "checking dump command (type=$type)"
221         rm -f $tmp.backup 2>>/dev/null
222         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
223                         -c "dump -$type -f $tmp.backup" \
224                         $SCRATCH_MNT | _filter_scratch
225 }
226
227 test_restore()
228 {
229         echo "checking restore command (type=$type)"
230         $XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
231                         -c "restore -$type -f $tmp.backup" \
232                         $SCRATCH_MNT | _filter_scratch
233 }
234
235 wipe_scratch()
236 {
237         wipe_mounts
238         _scratch_mkfs_xfs >>$seqres.full 2>&1
239 }
240
241 qmount_idmapped()
242 {
243         wipe_mounts
244         _try_scratch_mount || _fail "qmount failed"
245
246         mkdir -p "${SCRATCH_MNT}/unmapped"
247         mkdir -p "${SCRATCH_MNT}/idmapped"
248
249         $here/src/idmapped-mounts/mount-idmapped \
250                 --map-mount b:$id:$id2:1 \
251                 --map-mount b:0:0:1 \
252                 "$SCRATCH_MNT/unmapped" "$SCRATCH_MNT/idmapped" || _fail "mount-idmapped failed"
253
254         chmod ugo+rwx $SCRATCH_MNT
255         chmod ugo+rwx $SCRATCH_MNT/unmapped
256         chmod ugo+rwx $SCRATCH_MNT/idmapped
257 }
258
259 test_xfs_quota()
260 {
261         local quota_options="$1"
262
263         # init quota
264         echo "init quota limit and timer, and dump it"
265         if [ "$idmapped" -eq 1 ]; then
266                 echo "create_files_idmapped 1024k 15"; create_files_idmapped 1024k 15
267         else
268                 echo "create_files_unmapped 1024k 15"; create_files_unmapped 1024k 15
269         fi
270         echo "quota remount"; qmount_idmapped
271         echo ; test_quot
272         echo ; test_timer
273         echo ; test_limit 512k 2048k 10 20
274         echo ; test_dump
275
276         # report options test
277         echo "report options test"
278         echo ; test_report
279         echo "-N option"; test_report -N
280         echo "-L -U options"; test_report -L $id -U $id
281         echo "-t option"; test_report -t
282         echo "-n option"; test_report -n
283         echo "-h option"; test_report -h
284
285         # quot options test
286         echo "quot options test"
287         echo ; test_quot
288         echo "-f option"; test_quot -f $tmp.quot
289         cat $tmp.quot | filter_quot
290         echo "-n option"; test_quot -n
291
292         # quota options test
293         echo ; test_quota
294         echo "-f option"; test_quota -f $tmp.quota
295         cat $tmp.quota | filter_quota
296         echo "-N option"; test_quota -N
297         echo "-n option"; test_quota -n
298         echo "-h option"; test_quota -h
299
300         # disable/enable test
301         echo "disable quota"
302         echo ; test_disable
303         echo ; test_report -N
304         echo "expect a remove error at here"; test_remove
305         echo ; test_enable
306         echo ; test_report -N
307
308         # off and remove test
309         echo "off and remove test"
310         echo ; test_limit 100m 100m 100 100
311         echo ; test_quota -N
312         echo ; test_off
313         echo ; test_state
314         echo ; test_remove
315         echo ; test_report -N
316         echo "quota remount"
317         _qmount_option "$quota_options"
318         _qmount
319         qmount_idmapped
320         echo ; test_report -N
321
322         # restore test
323         echo "restore quota"
324         echo ; test_restore
325         echo ; test_report -N
326         echo ; test_state
327         echo "cleanup files"; clean_files
328 }
329
330 echo "----------------------- uquota,sync,unmapped ---------------------------"
331 wipe_scratch
332 _qmount_option "uquota,sync"
333 type=u
334 id=$uqid
335 id2=$uqid2
336 idmapped=0
337 qmount_idmapped
338 test_xfs_quota "uquota,sync"
339
340 echo "----------------------- uquota,sync,idmapped ---------------------------"
341 wipe_scratch
342 _qmount_option "uquota,sync"
343 type=u
344 id=$uqid
345 id2=$uqid2
346 idmapped=1
347 qmount_idmapped
348 test_xfs_quota "uquota,sync"
349
350 echo "----------------------- gquota,sync,unmapped ---------------------------"
351 wipe_scratch
352 _qmount_option "gquota,sync"
353 type=g
354 id=$gqid
355 id2=$gqid2
356 idmapped=0
357 qmount_idmapped
358 test_xfs_quota "gquota,sync"
359
360 echo "----------------------- gquota,sync,idmapped ---------------------------"
361 wipe_scratch
362 _qmount_option "gquota,sync"
363 type=g
364 id=$gqid
365 id2=$gqid2
366 idmapped=1
367 qmount_idmapped
368 test_xfs_quota "gquota,sync"
369
370 wipe_mounts
371
372 # success, all done
373 status=0
374 exit