overlay: add fsck.overlay whiteout test
[xfstests-dev.git] / tests / overlay / 201
1 #! /bin/bash
2 # FS QA Test 201
3 #
4 # Test fsck.overlay how to deal with whiteouts in overlayfs.
5 #
6 #-----------------------------------------------------------------------
7 # Copyright (c) 2018 Huawei.  All Rights Reserved.
8 # Author: zhangyi (F) <yi.zhang@huawei.com>
9 #
10 # This program is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU General Public License as
12 # published by the Free Software Foundation.
13 #
14 # This program is distributed in the hope that it would be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write the Free Software Foundation,
21 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22 #-----------------------------------------------------------------------
23 #
24
25 seq=`basename $0`
26 seqres=$RESULT_DIR/$seq
27 echo "QA output created by $seq"
28
29 here=`pwd`
30 tmp=/tmp/$$
31 status=1        # failure is the default!
32 trap "_cleanup; exit \$status" 0 1 2 3 15
33
34 _cleanup()
35 {
36         cd /
37         rm -f $tmp.*
38 }
39
40 # get standard environment, filters and checks
41 . ./common/rc
42 . ./common/filter
43 . ./common/attr
44
45 # remove previous $seqres.full before test
46 rm -f $seqres.full
47
48 # real QA test starts here
49 _supported_fs overlay
50 _supported_os Linux
51 _require_scratch_nocheck
52 _require_attrs
53 _require_command "$FSCK_OVERLAY_PROG" fsck.overlay
54
55 OVL_XATTR_OPAQUE_VAL=y
56
57 # remove all files from previous tests
58 _scratch_mkfs
59
60 # Check whiteout
61 check_whiteout()
62 {
63         for arg in $*; do
64                 local ttype=`stat -c "%F:%t,%T" $arg`
65
66                 [[ "$ttype" == "character special file:0,0" ]] || \
67                         echo "Valid whiteout removed incorrectly"
68         done
69 }
70
71 # Create a whiteout
72 make_whiteout()
73 {
74         for arg in $*; do
75                 mknod $arg c 0 0
76         done
77 }
78
79 # Create an opaque directory
80 make_opaque_dir()
81 {
82         local target=$1
83
84         mkdir -p $target
85         $SETFATTR_PROG -n $OVL_XATTR_OPAQUE -v $OVL_XATTR_OPAQUE_VAL $target
86 }
87
88 # Create a redirect directory
89 make_redirect_dir()
90 {
91         local target=$1
92         local value=$2
93
94         mkdir -p $target
95         $SETFATTR_PROG -n $OVL_XATTR_REDIRECT -v $value $target
96 }
97
98 # Create test directories
99 lowerdir=$OVL_BASE_SCRATCH_MNT/lower
100 lowerdir2=$OVL_BASE_SCRATCH_MNT/lower2
101 upperdir=$OVL_BASE_SCRATCH_MNT/upper
102 workdir=$OVL_BASE_SCRATCH_MNT/workdir
103
104 make_test_dirs()
105 {
106         rm -rf $lowerdir $lowerdir2 $upperdir $workdir
107         mkdir -p $lowerdir $lowerdir2 $upperdir $workdir
108 }
109
110 # Test orphan whiteout in lower and upper layer, should remove
111 echo "+ Orphan whiteout"
112 make_test_dirs
113 make_whiteout $lowerdir/foo $upperdir/{foo,bar}
114
115 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
116         echo "fsck should not fail"
117 ls $lowerdir
118 ls $upperdir
119
120 # Test valid whiteout covering lower target, should not remove
121 echo "+ Valid whiteout"
122 make_test_dirs
123 touch $lowerdir2/{foo,bar}
124 make_whiteout $upperdir/foo $lowerdir/bar
125
126 _overlay_fsck_dirs "$lowerdir:$lowerdir2" $upperdir $workdir -p >> \
127          $seqres.full 2>&1 || echo "fsck should not fail"
128 check_whiteout $upperdir/foo $lowerdir/bar
129
130 # Test orphan whiteout in opaque directory, should remove
131 echo "+ Orphan whiteout(2)"
132 make_test_dirs
133 mkdir $lowerdir/testdir
134 touch $lowerdir/testdir/foo
135 make_opaque_dir $upperdir/testdir
136 make_whiteout $upperdir/testdir/foo
137
138 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
139         echo "fsck should not fail"
140 ls $upperdir/testdir
141
142 # Test orphan whiteout whose parent path is not an merged directory,
143 # should remove
144 echo "+ Orphan whiteout(3)"
145 make_test_dirs
146 mkdir $lowerdir2/{testdir1,testdir2,testdir3}
147 touch $lowerdir2/{testdir1/foo,testdir2/foo,testdir3/foo}
148 mkdir $upperdir/{testdir1,testdir2,testdir3,testdir4}
149 touch $lowerdir/testdir1
150 make_whiteout $lowerdir/testdir2
151 make_opaque_dir $lowerdir/testdir3
152 make_whiteout $upperdir/{testdir1/foo,/testdir2/foo,testdir3/foo,testdir4/foo}
153
154 _overlay_fsck_dirs "$lowerdir:$lowerdir2" $upperdir $workdir -p >> \
155         $seqres.full 2>&1 || echo "fsck should not fail"
156 ls $upperdir/testdir1
157 ls $upperdir/testdir2
158 ls $upperdir/testdir3
159 ls $upperdir/testdir4
160
161 # Test orphan whiteout in redirect directory, should remove
162 echo "+ Orphan whiteout(4)"
163 make_test_dirs
164 mkdir $lowerdir/{testdir,origin}
165 touch $lowerdir/testdir/foo
166 make_redirect_dir $upperdir/testdir "origin"
167 make_whiteout $upperdir/testdir/foo
168
169 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
170         echo "fsck should not fail"
171 ls $upperdir/testdir
172
173 # Test valid whiteout in redirect directory cover file in lower
174 # redirect origin directory, should not remove
175 echo "+ Valid whiteout(2)"
176 make_test_dirs
177 mkdir $lowerdir/origin
178 touch $lowerdir/origin/foo
179 make_redirect_dir $upperdir/testdir "origin"
180 make_whiteout $upperdir/testdir/foo
181
182 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
183         echo "fsck should not fail"
184 check_whiteout $upperdir/testdir/foo
185
186 # Test valid whiteout covering lower target whose parent directory
187 # merge with a redirect directory in the middle layer, should not remove.
188 echo "+ Valid whiteout(3)"
189 make_test_dirs
190 mkdir -p $lowerdir2/origin/subdir
191 touch $lowerdir2/origin/subdir/foo
192 make_redirect_dir $lowerdir/testdir "origin"
193 mkdir -p $upperdir/testdir/subdir
194 make_whiteout $upperdir/testdir/subdir/foo
195
196 _overlay_fsck_dirs "$lowerdir:$lowerdir2" $upperdir $workdir -p \
197         >> $seqres.full 2>&1 || echo "fsck should not fail"
198 check_whiteout $upperdir/testdir/subdir/foo
199
200 # Test invalid whiteout in opaque subdirectory in a redirect directory,
201 # should remove
202 echo "+ Orphan whiteout(5)"
203 make_test_dirs
204 mkdir -p $lowerdir/origin/subdir
205 touch $lowerdir/origin/subdir/foo
206 make_redirect_dir $upperdir/testdir "origin"
207 make_opaque_dir $upperdir/testdir/subdir
208 make_whiteout $upperdir/testdir/subdir/foo
209
210 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
211         echo "fsck should not fail"
212 ls $upperdir/testdir/subdir
213
214 # Test valid whiteout in reidrect subdirectory in a opaque directory
215 # covering lower target, should not remove
216 echo "+ Valid whiteout(4)"
217 make_test_dirs
218 mkdir $lowerdir/origin
219 touch $lowerdir/origin/foo
220 make_opaque_dir $upperdir/testdir
221 make_redirect_dir $upperdir/testdir/subdir "/origin"
222 make_whiteout $upperdir/testdir/subdir/foo
223
224 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
225         echo "fsck should not fail"
226 check_whiteout $upperdir/testdir/subdir/foo
227
228 # success, all done
229 status=0
230 exit