xfs: test upgrading filesystem to bigtime
[xfstests-dev.git] / tests / xfs / 161
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Copyright (c) 2021 Oracle.  All Rights Reserved.
4 #
5 # FS QA Test No. 161
6 #
7 # Check that we can upgrade a filesystem to support bigtime and that quota
8 # timers work properly after the upgrade.  You need a quota-tools containing
9 # commit 16b60cb9e315ed for this test to run properly; v4.06 should do.
10
11 seq=`basename $0`
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
14
15 here=`pwd`
16 tmp=/tmp/$$
17 status=1    # failure is the default!
18 trap "_cleanup; exit \$status" 0 1 2 3 15
19
20 _cleanup()
21 {
22         cd /
23         rm -f $tmp.*
24 }
25
26 # get standard environment, filters and checks
27 . ./common/rc
28 . ./common/filter
29 . ./common/quota
30
31 # real QA test starts here
32 _supported_fs xfs
33 _require_command "$XFS_ADMIN_PROG" "xfs_admin"
34 _require_command "$QUOTA_PROG" "quota"
35 _require_quota
36 _require_scratch_xfs_bigtime
37 _require_xfs_repair_upgrade bigtime
38
39 # The word 'projectname' was added to quota(8)'s synopsis shortly after
40 # y2038+ support was added for XFS, so we use that to decide if we're going
41 # to run this test at all.
42 $QUOTA_PROG --help 2>&1 | grep -q projectname || \
43         _notrun 'quota: bigtime support not detected'
44
45 date --date='Jan 1 00:00:00 UTC 2040' > /dev/null 2>&1 || \
46         _notrun "Userspace does not support dates past 2038."
47
48 rm -f $seqres.full
49
50 # Format V5 filesystem without bigtime support and populate it
51 _scratch_mkfs -m crc=1,bigtime=0 >> $seqres.full
52 _qmount_option "usrquota"
53 _scratch_xfs_db -c 'version' -c 'sb 0' -c 'p' >> $seqres.full
54 _scratch_mount >> $seqres.full
55
56 # Force the block counters for uid 1 and 2 above zero
57 _pwrite_byte 0x61 0 64k $SCRATCH_MNT/a >> $seqres.full
58 _pwrite_byte 0x61 0 64k $SCRATCH_MNT/b >> $seqres.full
59 sync
60 chown 1 $SCRATCH_MNT/a
61 chown 2 $SCRATCH_MNT/b
62
63 # Set quota limits on uid 1 before upgrading
64 $XFS_QUOTA_PROG -x -c 'limit -u bsoft=12k bhard=1m 1' $SCRATCH_MNT
65
66 # Make sure the grace period is at /some/ point in the future.  We have to
67 # use bc because not all bashes can handle integer comparisons with 64-bit
68 # numbers.
69 repquota -upn $SCRATCH_MNT > $tmp.repquota
70 cat $tmp.repquota >> $seqres.full
71 grace="$(cat $tmp.repquota | grep '^#1' | awk '{print $6}')"
72 now="$(date +%s)"
73 res="$(echo "${grace} > ${now}" | $BC_PROG)"
74 test $res -eq 1 || echo "Expected timer expiry (${grace}) to be after now (${now})."
75
76 _scratch_unmount
77
78 # Now upgrade to bigtime support
79 _scratch_xfs_admin -O bigtime=1 2>> $seqres.full
80 _check_scratch_xfs_features BIGTIME
81 _check_scratch_fs
82 _scratch_xfs_db -c 'version' -c 'sb 0' -c 'p' >> $seqres.full
83
84 # Mount again, see if our quota timer survived
85 _scratch_mount
86
87 # Set a very generous grace period and quota limits on uid 2 after upgrading
88 $XFS_QUOTA_PROG -x -c 'timer -u -b -d 2147483647' $SCRATCH_MNT
89 $XFS_QUOTA_PROG -x -c 'limit -u bsoft=10000 bhard=150000 2' $SCRATCH_MNT
90
91 # Query the grace periods to see if they got set properly after the upgrade.
92 repquota -upn $SCRATCH_MNT > $tmp.repquota
93 cat $tmp.repquota >> $seqres.full
94 grace1="$(repquota -upn $SCRATCH_MNT | grep '^#1' | awk '{print $6}')"
95 grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')"
96 now="$(date +%s)"
97
98 # Make sure that uid 1's expiration is in the future...
99 res1="$(echo "${grace} > ${now}" | $BC_PROG)"
100 test "${res1}" -eq 1 || echo "Expected uid 1 expiry (${grace1}) to be after now (${now})."
101
102 # ...and that uid 2's expiration is after uid 1's...
103 res2="$(echo "${grace2} > ${grace1}" | $BC_PROG)"
104 test "${res2}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after uid 1 (${grace1})."
105
106 # ...and that uid 2's expiration is after 2038 if right now is far enough
107 # past 1970 that our generous grace period would provide for that.
108 res3="$(echo "(${now} < 100) || (${grace2} > 2147483648)" | $BC_PROG)"
109 test "${res3}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after 2038."
110
111 _scratch_cycle_mount
112
113 # Query the grace periods to see if they survived a remount.
114 repquota -upn $SCRATCH_MNT > $tmp.repquota
115 cat $tmp.repquota >> $seqres.full
116 grace1="$(repquota -upn $SCRATCH_MNT | grep '^#1' | awk '{print $6}')"
117 grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')"
118 now="$(date +%s)"
119
120 # Make sure that uid 1's expiration is in the future...
121 res1="$(echo "${grace} > ${now}" | $BC_PROG)"
122 test "${res1}" -eq 1 || echo "Expected uid 1 expiry (${grace1}) to be after now (${now})."
123
124 # ...and that uid 2's expiration is after uid 1's...
125 res2="$(echo "${grace2} > ${grace1}" | $BC_PROG)"
126 test "${res2}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after uid 1 (${grace1})."
127
128 # ...and that uid 2's expiration is after 2038 if right now is far enough
129 # past 1970 that our generous grace period would provide for that.
130 res3="$(echo "(${now} < 100) || (${grace2} > 2147483648)" | $BC_PROG)"
131 test "${res3}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after 2038."
132
133 # Now try setting uid 2's expiration to Feb 22 22:22:22 UTC 2222
134 new_expiry=$(date -d 'Feb 22 22:22:22 UTC 2222' +%s)
135 now=$(date +%s)
136 test $now -ge $new_expiry && \
137         echo "Now is after February 2222?  Expect problems."
138 expiry_delta=$((new_expiry - now))
139
140 echo "setting expiration to $new_expiry - $now = $expiry_delta" >> $seqres.full
141 $XFS_QUOTA_PROG -x -c "timer -u $expiry_delta 2" -c 'report' $SCRATCH_MNT >> $seqres.full
142
143 # Did we get an expiration within 5s of the target range?
144 grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')"
145 echo "grace2 is $grace2" >> $seqres.full
146 _within_tolerance "grace2 expiry" $grace2 $new_expiry 5 -v
147
148 _scratch_cycle_mount
149
150 # ...and is it still within 5s after a remount?
151 grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')"
152 echo "grace2 is $grace2" >> $seqres.full
153 _within_tolerance "grace2 expiry after remount" $grace2 $new_expiry 5 -v
154
155 # success, all done
156 status=0
157 exit