#! /bin/bash # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (c) 2021 Oracle. All Rights Reserved. # # FS QA Test No. 161 # # Check that we can upgrade a filesystem to support bigtime and that quota # timers work properly after the upgrade. You need a quota-tools containing # commit 16b60cb9e315ed for this test to run properly; v4.06 should do. . ./common/preamble _begin_fstest auto quick bigtime quota # Import common functions. . ./common/filter . ./common/quota # real QA test starts here _supported_fs xfs _require_command "$XFS_ADMIN_PROG" "xfs_admin" _require_command "$QUOTA_PROG" "quota" _require_quota _require_scratch_xfs_bigtime _require_xfs_repair_upgrade bigtime # The word 'projectname' was added to quota(8)'s synopsis shortly after # y2038+ support was added for XFS, so we use that to decide if we're going # to run this test at all. $QUOTA_PROG --help 2>&1 | grep -q projectname || \ _notrun 'quota: bigtime support not detected' date --date='Jan 1 00:00:00 UTC 2040' > /dev/null 2>&1 || \ _notrun "Userspace does not support dates past 2038." # Format V5 filesystem without bigtime support and populate it _scratch_mkfs -m crc=1,bigtime=0 >> $seqres.full _qmount_option "usrquota" _scratch_xfs_db -c 'version' -c 'sb 0' -c 'p' >> $seqres.full _scratch_mount >> $seqres.full # Force the block counters for uid 1 and 2 above zero _pwrite_byte 0x61 0 64k $SCRATCH_MNT/a >> $seqres.full _pwrite_byte 0x61 0 64k $SCRATCH_MNT/b >> $seqres.full sync chown 1 $SCRATCH_MNT/a chown 2 $SCRATCH_MNT/b # Set quota limits on uid 1 before upgrading $XFS_QUOTA_PROG -x -c 'limit -u bsoft=12k bhard=1m 1' $SCRATCH_MNT # Make sure the grace period is at /some/ point in the future. We have to # use bc because not all bashes can handle integer comparisons with 64-bit # numbers. repquota -upn $SCRATCH_MNT > $tmp.repquota cat $tmp.repquota >> $seqres.full grace="$(cat $tmp.repquota | grep '^#1' | awk '{print $6}')" now="$(date +%s)" res="$(echo "${grace} > ${now}" | $BC_PROG)" test $res -eq 1 || echo "Expected timer expiry (${grace}) to be after now (${now})." _scratch_unmount # Now upgrade to bigtime support _scratch_xfs_admin -O bigtime=1 2>> $seqres.full _check_scratch_xfs_features BIGTIME _check_scratch_fs _scratch_xfs_db -c 'version' -c 'sb 0' -c 'p' >> $seqres.full # Mount again, see if our quota timer survived _scratch_mount # Set a very generous grace period and quota limits on uid 2 after upgrading $XFS_QUOTA_PROG -x -c 'timer -u -b -d 2147483647' $SCRATCH_MNT $XFS_QUOTA_PROG -x -c 'limit -u bsoft=10000 bhard=150000 2' $SCRATCH_MNT # Query the grace periods to see if they got set properly after the upgrade. repquota -upn $SCRATCH_MNT > $tmp.repquota cat $tmp.repquota >> $seqres.full grace1="$(repquota -upn $SCRATCH_MNT | grep '^#1' | awk '{print $6}')" grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')" now="$(date +%s)" # Make sure that uid 1's expiration is in the future... res1="$(echo "${grace} > ${now}" | $BC_PROG)" test "${res1}" -eq 1 || echo "Expected uid 1 expiry (${grace1}) to be after now (${now})." # ...and that uid 2's expiration is after uid 1's... res2="$(echo "${grace2} > ${grace1}" | $BC_PROG)" test "${res2}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after uid 1 (${grace1})." # ...and that uid 2's expiration is after 2038 if right now is far enough # past 1970 that our generous grace period would provide for that. res3="$(echo "(${now} < 100) || (${grace2} > 2147483648)" | $BC_PROG)" test "${res3}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after 2038." _scratch_cycle_mount # Query the grace periods to see if they survived a remount. repquota -upn $SCRATCH_MNT > $tmp.repquota cat $tmp.repquota >> $seqres.full grace1="$(repquota -upn $SCRATCH_MNT | grep '^#1' | awk '{print $6}')" grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')" now="$(date +%s)" # Make sure that uid 1's expiration is in the future... res1="$(echo "${grace} > ${now}" | $BC_PROG)" test "${res1}" -eq 1 || echo "Expected uid 1 expiry (${grace1}) to be after now (${now})." # ...and that uid 2's expiration is after uid 1's... res2="$(echo "${grace2} > ${grace1}" | $BC_PROG)" test "${res2}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after uid 1 (${grace1})." # ...and that uid 2's expiration is after 2038 if right now is far enough # past 1970 that our generous grace period would provide for that. res3="$(echo "(${now} < 100) || (${grace2} > 2147483648)" | $BC_PROG)" test "${res3}" -eq 1 || echo "Expected uid 2 expiry (${grace2}) to be after 2038." # Now try setting uid 2's expiration to Feb 22 22:22:22 UTC 2222 new_expiry=$(date -d 'Feb 22 22:22:22 UTC 2222' +%s) now=$(date +%s) test $now -ge $new_expiry && \ echo "Now is after February 2222? Expect problems." expiry_delta=$((new_expiry - now)) echo "setting expiration to $new_expiry - $now = $expiry_delta" >> $seqres.full $XFS_QUOTA_PROG -x -c "timer -u $expiry_delta 2" -c 'report' $SCRATCH_MNT >> $seqres.full # Did we get an expiration within 5s of the target range? grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')" echo "grace2 is $grace2" >> $seqres.full _within_tolerance "grace2 expiry" $grace2 $new_expiry 5 -v _scratch_cycle_mount # ...and is it still within 5s after a remount? grace2="$(repquota -upn $SCRATCH_MNT | grep '^#2' | awk '{print $6}')" echo "grace2 is $grace2" >> $seqres.full _within_tolerance "grace2 expiry after remount" $grace2 $new_expiry 5 -v # success, all done status=0 exit