f742feddc85f13af8d620f32b67e28565518af10
[xfstests-dev.git] / tests / generic / 402
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2016 Deepa Dinamani.  All Rights Reserved.
4 #
5 # FS QA Test 402
6 #
7 # Tests to verify policy for filesystem timestamps for
8 # supported ranges:
9 # 1. Verify filesystem rw mount according to sysctl
10 # timestamp_supported.
11 # 2. Verify timestamp clamping for timestamps beyond max
12 # timestamp supported.
13 #
14 # Exit status 1: either or both tests above fail.
15 # Exit status 0: both the above tests pass.
16 #
17 seq=`basename $0`
18 seqres=$RESULT_DIR/$seq
19 echo "QA output created by $seq"
20
21 here=`pwd`
22 tmp=/tmp/$$
23 status=1        # failure is the default!
24 trap "exit \$status" 0 1 2 3 15
25
26 # Get standard environment, filters and checks.
27 . ./common/rc
28 . ./common/filter
29 . ./common/attr
30
31 # remove previous $seqres.full before test
32 rm -f $seqres.full
33
34 # Prerequisites for the test run.
35 _supported_fs generic
36 _supported_os Linux
37 _require_scratch
38 _require_xfs_io_command utimes
39
40 # Compare file timestamps obtained from stat
41 # with a given timestamp.
42 check_stat()
43 {
44         file=$1
45         timestamp=$2
46
47         stat_timestamp=`stat -c"%X;%Y" $file`
48
49         prev_timestamp="$timestamp;$timestamp"
50         if [ $prev_timestamp != $stat_timestamp ]; then
51                 echo "$prev_timestamp != $stat_timestamp" | tee -a $seqres.full
52         fi
53 }
54
55 run_test_individual()
56 {
57         file=$1
58         timestamp=$2
59         update_time=$3
60
61         # check if the time needs update
62         if [ $update_time -eq 1 ]; then
63                 echo "Updating file: $file to timestamp `date -d @$timestamp`"  >> $seqres.full
64                 $XFS_IO_PROG -f -c "utimes $timestamp 0 $timestamp 0" $file
65                 if [ $? -ne 0 ]; then
66                         echo "Failed to update times on $file" | tee -a $seqres.full
67                 fi
68         fi
69
70         tsclamp=$(($timestamp>$tsmax?$tsmax:$timestamp))
71         echo "Checking file: $file Updated timestamp is `date -d @$tsclamp`"  >> $seqres.full
72         check_stat $file $tsclamp
73 }
74
75 run_test()
76 {
77         update_time=$1
78
79         n=1
80
81         for TIME in "${TIMESTAMPS[@]}"; do
82                 run_test_individual ${SCRATCH_MNT}/test_$n $TIME $update_time
83                 ((n++))
84         done
85 }
86
87 _scratch_mkfs &>> $seqres.full 2>&1 || _fail "mkfs failed"
88 _require_y2038 $SCRATCH_DEV
89
90 read tsmin tsmax <<<$(_filesystem_timestamp_range $SCRATCH_DEV)
91 echo min supported timestamp $tsmin $(date --date=@$tsmin) >> $seqres.full
92 echo max supported timestamp $tsmax $(date --date=@$tsmax) >> $seqres.full
93
94 # Test timestamps array
95
96 declare -a TIMESTAMPS=(
97         $tsmin
98         0
99         $tsmax
100         $((tsmax+1))
101         4294967295
102         8589934591
103         34359738367
104 )
105
106 # Max timestamp is hardcoded to Mon Jan 18 19:14:07 PST 2038
107 sys_tsmax=2147483647
108 echo "max timestamp that needs to be supported by fs for rw mount is" \
109         "$((sys_tsmax+1)) $(date --date=@$((sys_tsmax+1)))" >> $seqres.full
110
111 read ts_check <<<$(cat /proc/sys/fs/fs-timestamp-check-on)
112
113 _scratch_mount
114 result=$?
115
116 if [ $ts_check -ne 0 ]; then
117         echo "sysctl filesystem timestamp check is on" >> $seqres.full
118         # check for mount failure if the minimum requirement for max timestamp
119         # supported is not met.
120         if [ $sys_tsmax -ge $tsmax ]; then
121                 if [ $result -eq 0 ]; then
122                         echo "mount test failed"  | tee -a $seqres.full
123                         exit
124                 fi
125         else
126                 if [ $result -ne 0 ]; then
127                         echo "failed to mount $SCRATCH_DEV"  | tee -a $seqres.full
128                         exit
129                 fi
130         fi
131 else
132         # if sysctl switch is off then mount should succeed always.
133         echo "sysctl filesystem timestamp check is off" >> $seqres.full
134         if [ $result -ne 0 ]; then
135                 echo "failed to mount $SCRATCH_DEV and timestamp check is off"  >> $seqres.full
136                 exit
137         fi
138 fi
139
140 # Begin test case 1
141 echo "In memory timestamps update test start" >> $seqres.full
142
143 # update time on the file
144 update_time=1
145
146 run_test $update_time
147
148 echo "In memory timestamps update complete" >> $seqres.full
149
150 echo "Unmounting and mounting scratch $SCRATCH_MNT" >> $seqres.full
151
152 # unmount and remount $SCRATCH_DEV
153 _scratch_cycle_mount
154
155 # Begin test case 2
156
157 n=1
158
159 # Do not update time on the file this time, just read from disk
160 update_time=0
161
162 echo "On disk timestamps update test start" >> $seqres.full
163
164 # Re-run test
165 run_test $update_time
166
167 echo "On disk timestamps update test complete" >> $seqres.full
168
169 echo "y2038 inode timestamp tests completed successfully"
170
171 # success, all done
172 status=0
173 exit