overlay: Add tests for overlay metadata only copy up feature
[xfstests-dev.git] / tests / overlay / 060
1 #! /bin/bash
2 # FS QA Test No. 060
3 #
4 # Test metadata only copy up functionality.
5 #
6 #-----------------------------------------------------------------------
7 # Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
8 #
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License as
11 # published by the Free Software Foundation.
12 #
13 # This program is distributed in the hope that it would be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write the Free Software Foundation,
20 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 #-----------------------------------------------------------------------
22 #
23
24 seq=`basename $0`
25 seqres=$RESULT_DIR/$seq
26 echo "QA output created by $seq"
27
28 here=`pwd`
29 tmp=/tmp/$$
30 status=1        # failure is the default!
31 trap "_cleanup; exit \$status" 0 1 2 3 15
32
33 _cleanup()
34 {
35         cd /
36         rm -f $tmp.*
37 }
38
39 # get standard environment, filters and checks
40 . ./common/rc
41 . ./common/filter
42
43 # remove previous $seqres.full before test
44 rm -f $seqres.full
45
46 # real QA test starts here
47 _supported_fs overlay
48 _supported_os Linux
49 # We use non-default scratch underlying overlay dirs, we need to check
50 # them explicity after test.
51 _require_scratch_nocheck
52 _require_scratch_overlay_features index redirect_dir metacopy
53
54 # remove all files from previous tests
55 _scratch_mkfs
56
57 # File size on lower
58 lowername="lowerfile"
59 lowerlink="lowerfile-link"
60 lowerdata="lower"
61 lowersize="4096"
62
63 # Number of blocks allocated by filesystem on lower. Will be queried later.
64 lowerblocks=""
65
66 udirname="pureupper"
67 ufile="upperfile"
68
69 # Check metacopy xattr
70 check_metacopy()
71 {
72         local target=$1 exist=$2
73         local out_f target_f
74         local msg
75
76         out_f=$($GETFATTR_PROG --absolute-names --only-values -n \
77                 $OVL_XATTR_METACOPY $target 2>&1 | _filter_scratch)
78
79         if [ "$exist" == "y" ];then
80                 [ "$out_f" == "" ] && return
81                 echo "Metacopy xattr does not exist on ${target}. stdout=$out_f"
82                 return
83         fi
84
85         if [ "$out_f" == "" ];then
86                 echo "Metacopy xattr exists on ${target} unexpectedly."
87                 return
88         fi
89
90         target_f=`echo $target | _filter_scratch`
91         msg="$target_f: trusted.overlay.metacopy: No such attribute"
92
93         [ "$out_f" == "$msg" ] && return
94
95         echo "Error while checking xattr on ${target}. stdout=$out"
96 }
97
98 # Check redirect xattr
99 check_redirect()
100 {
101         local target=$1
102         local expect=$2
103
104         value=$($GETFATTR_PROG --absolute-names --only-values -n \
105                 $OVL_XATTR_REDIRECT $target)
106
107         [[ "$value" == "$expect" ]] || echo "Redirect xattr incorrect. Expected=\"$expect\", actual=\"$value\""
108 }
109
110 # Check size
111 check_file_size()
112 {
113         local target=$1 expected_size=$2 actual_size
114
115         actual_size=$(stat -c "%s" $target)
116
117         [ "$actual_size" == "$expected_size" ] || echo "Expected file size $expected_size but actual size is $actual_size"
118 }
119
120 check_file_blocks()
121 {
122         local target=$1 expected_blocks=$2 nr_blocks
123
124         nr_blocks=$(stat -c "%b" $target)
125
126         [ "$nr_blocks" == "$expected_blocks" ] || echo "Expected $expected_blocks blocks but actual number of blocks is ${nr_blocks}."
127 }
128
129 check_file_contents()
130 {
131         local target=$1 expected=$2
132         local actual target_f
133
134         target_f=`echo $target | _filter_scratch`
135
136         read actual<$target
137
138         [ "$actual" == "$expected" ] || echo "Expected file $target_f contents to be \"$expected\" but actual contents are \"$actual\""
139 }
140
141 check_file_size_contents()
142 {
143         local target=$1 expected_size=$2 expected_content=$3
144
145         check_file_size $target $expected_size
146         check_file_contents $target $expected_content
147 }
148
149 mount_overlay()
150 {
151         local _lowerdir=$1
152
153         _overlay_scratch_mount_dirs "$_lowerdir" $upperdir $workdir -o redirect_dir=on,index=on,metacopy=on
154 }
155
156 umount_overlay()
157 {
158         $UMOUNT_PROG $SCRATCH_MNT
159 }
160
161 # Assumes it is called with overlay mounted.
162 test_common()
163 {
164         local _lowerdir=$1 _target=$2 _size=$3 _blocks=$4 _data="$5"
165         local _redirect=$6
166
167         echo "check properties of metadata copied up file"
168         check_file_size_contents $SCRATCH_MNT/$_target $_size "$_data"
169         check_file_blocks $SCRATCH_MNT/$_target $_blocks
170
171         # Do a mount cycle and check size and contents again.
172         echo "Unmount and Mount again"
173         umount_overlay
174         mount_overlay $_lowerdir
175         echo "check properties of metadata copied up file"
176         check_file_size_contents $SCRATCH_MNT/$_target $_size "$_data"
177         check_file_blocks $SCRATCH_MNT/$_target $_blocks
178
179         # Make sure copied up file is a metacopy file.
180         umount_overlay
181         check_metacopy $upperdir/$_target "y"
182         check_file_size_contents $upperdir/$_target $_size ""
183         [ -n "$_redirect" ] && check_redirect $upperdir/$_target "$_redirect"
184
185         # Trigger data copy up and check absence of metacopy xattr.
186         mount_overlay $_lowerdir
187         $XFS_IO_PROG -c "open -a $SCRATCH_MNT/$_target"
188         echo "check properties of data copied up file"
189         check_file_size_contents $SCRATCH_MNT/$_target $_size "$_data"
190         umount_overlay
191         check_metacopy $upperdir/$_target "n"
192         check_file_size_contents $upperdir/$_target $_size "$_data"
193 }
194
195 create_basic_files()
196 {
197         _scratch_mkfs
198         mkdir -p $lowerdir $lowerdir2 $upperdir $workdir $workdir2
199         mkdir -p $upperdir/$udirname
200         echo "$lowerdata" > $lowerdir/$lowername
201         chmod 600 $lowerdir/$lowername
202         # Create a file of size lowersize.
203         $XFS_IO_PROG -c "falloc 0 $lowersize" $lowerdir/$lowername
204         $XFS_IO_PROG -c "fsync" $lowerdir/$lowername
205
206         # Query number of lower
207         lowerblocks=$(stat -c "%b" $lowerdir/$lowername)
208 }
209
210 create_lower_link()
211 {
212         ln $lowerdir/$lowername $lowerdir/$lowerlink
213 }
214
215 prepare_midlayer()
216 {
217         _scratch_mkfs
218         create_basic_files
219         # Create midlayer
220         _overlay_scratch_mount_dirs $lowerdir $lowerdir2 $workdir2 -o redirect_dir=on,index=on,metacopy=on
221         # Trigger a metacopy
222         chmod 400 $SCRATCH_MNT/$lowername
223         umount_overlay
224 }
225
226 # Create test directories
227 lowerdir=$OVL_BASE_SCRATCH_MNT/lower
228 lowerdir2=$OVL_BASE_SCRATCH_MNT/lower2
229 upperdir=$OVL_BASE_SCRATCH_MNT/upper
230 workdir=$OVL_BASE_SCRATCH_MNT/workdir
231 workdir2=$OVL_BASE_SCRATCH_MNT/workdir2
232
233 # Tests start here
234 echo "== Check Simple Metacopy =="
235 create_basic_files
236 mount_overlay $lowerdir
237 chmod 400 $SCRATCH_MNT/$lowername
238 test_common $lowerdir $lowername $lowersize $lowerblocks "$lowerdata"
239
240 # Test midlayer metacopy
241 echo -e "\n== Check Midlayer Metacopy =="
242 prepare_midlayer
243 mount_overlay "$lowerdir2:$lowerdir"
244 chmod 400 $SCRATCH_MNT/$lowername
245 test_common "$lowerdir2:$lowerdir" $lowername $lowersize $lowerblocks \
246                 "$lowerdata"
247
248 # Test Rename Redirect
249 echo -e "\n== Check Rename Redirect =="
250 create_basic_files
251 mount_overlay $lowerdir
252 mv $SCRATCH_MNT/$lowername $SCRATCH_MNT/$ufile
253 test_common $lowerdir $ufile $lowersize $lowerblocks "$lowerdata" "$lowername"
254
255 # Test midlayer rename redirect
256 echo -e "\n== Check Midlayer Rename Redirect =="
257 prepare_midlayer
258 mount_overlay "$lowerdir2:$lowerdir"
259 mv $SCRATCH_MNT/$lowername $SCRATCH_MNT/$ufile
260 test_common "$lowerdir2:$lowerdir" $ufile $lowersize $lowerblocks "$lowerdata" \
261                 "$lowername"
262
263 # Test Link Redirect
264 echo -e "\n== Check Link Redirect =="
265 create_basic_files
266 mount_overlay $lowerdir
267 ln $SCRATCH_MNT/$lowername $SCRATCH_MNT/$udirname/$ufile
268 test_common $lowerdir $udirname/$ufile $lowersize $lowerblocks "$lowerdata" \
269                 "/$lowername"
270
271 # Test midlayer link redirect
272 echo -e "\n== Check Midlayer Link Redirect =="
273 prepare_midlayer
274 mount_overlay "$lowerdir2:$lowerdir"
275 ln $SCRATCH_MNT/$lowername $SCRATCH_MNT/$udirname/$ufile
276 test_common "$lowerdir2:$lowerdir" $udirname/$ufile $lowersize $lowerblocks \
277                 "$lowerdata" "/$lowername"
278
279 # Test lower link file gets absolute redirect upon rename
280 echo -e "\n== Check Lower Link Rename Absolute Redirect =="
281 create_basic_files
282 create_lower_link
283 mount_overlay $lowerdir
284 mv $SCRATCH_MNT/$lowerlink $SCRATCH_MNT/$ufile
285 test_common $lowerdir $ufile $lowersize $lowerblocks "$lowerdata" "/$lowerlink"
286
287 # success, all done
288 status=0
289 exit