overlay: add fsck.overlay redirect directory test
[xfstests-dev.git] / tests / overlay / 202
1 #! /bin/bash
2 # FS QA Test 202
3 #
4 # Test fsck.overlay how to deal with redirect xattr 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 # remove all files from previous tests
56 _scratch_mkfs
57
58 OVL_XATTR_OPAQUE_VAL=y
59
60 # Create a redirect directory
61 make_redirect_dir()
62 {
63         local target=$1
64         local value=$2
65
66         mkdir -p $target
67         $SETFATTR_PROG -n $OVL_XATTR_REDIRECT -v $value $target
68 }
69
70 # Check redirect xattr
71 check_redirect()
72 {
73         local target=$1
74         local expect=$2
75
76         value=$($GETFATTR_PROG --absolute-names --only-values -n \
77                 $OVL_XATTR_REDIRECT $target)
78
79         [[ "$value" == "$expect" ]] || echo "Redirect xattr incorrect"
80 }
81
82 check_no_redirect()
83 {
84         local target=$1
85
86         value=$($GETFATTR_PROG --absolute-names -d -m \
87                 $OVL_XATTR_REDIRECT $target)
88
89         [[ -z "$value" ]] || echo "Redirect xattr not empty"
90 }
91
92 # Check opaque xattr
93 check_opaque()
94 {
95         local target=$1
96
97         value=$($GETFATTR_PROG --absolute-names --only-values -n \
98                 $OVL_XATTR_OPAQUE $target)
99
100         [[ "$value" == "$OVL_XATTR_OPAQUE_VAL" ]] || \
101                 echo "Opaque xattr incorrect"
102 }
103
104 # Create a whiteout
105 make_whiteout()
106 {
107         for arg in $*; do
108                 mknod $arg c 0 0
109         done
110 }
111
112 # Check whiteout
113 check_whiteout()
114 {
115         for arg in $*; do
116                 local ttype=`stat -c "%F:%t,%T" $arg`
117
118                 [[ "$ttype" == "character special file:0,0" ]] || \
119                         echo "Valid whiteout removed incorrectly"
120         done
121 }
122
123 # Create test directories
124 lowerdir=$OVL_BASE_SCRATCH_MNT/lower
125 lowerdir2=$OVL_BASE_SCRATCH_MNT/lower2
126 upperdir=$OVL_BASE_SCRATCH_MNT/upper
127 workdir=$OVL_BASE_SCRATCH_MNT/workdir
128
129 make_test_dirs()
130 {
131         rm -rf $lowerdir $lowerdir2 $upperdir $workdir
132         mkdir -p $lowerdir $lowerdir2 $upperdir $workdir
133 }
134
135 # Test invalid redirect xattr point to a nonexistent origin, should remove
136 echo "+ Invalid redirect"
137 make_test_dirs
138 make_redirect_dir $upperdir/testdir "invalid"
139
140 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
141         echo "fsck should not fail"
142 check_no_redirect $upperdir/testdir
143
144 # Test invalid redirect xattr point to a file origin, should remove
145 echo "+ Invalid redirect(2)"
146 make_test_dirs
147 touch $lowerdir/origin
148 make_redirect_dir $upperdir/testdir "origin"
149
150 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
151         echo "fsck should not fail"
152 check_no_redirect $upperdir/testdir
153
154 # Test valid redirect xattr point to a directory origin in the same directory,
155 # should not remove
156 echo "+ Valid redirect"
157 make_test_dirs
158 mkdir $lowerdir/origin
159 make_whiteout $upperdir/origin
160 make_redirect_dir $upperdir/testdir "origin"
161
162 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
163         echo "fsck should not fail"
164 check_redirect $upperdir/testdir "origin"
165
166 # Test valid redirect xattr point to a directory origin in different directories
167 # should not remove
168 echo "+ Valid redirect(2)"
169 make_test_dirs
170 mkdir $lowerdir/origin
171 make_whiteout $upperdir/origin
172 make_redirect_dir $upperdir/testdir1/testdir2 "/origin"
173
174 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
175         echo "fsck should not fail"
176 check_redirect $upperdir/testdir1/testdir2 "/origin"
177
178 # Test valid redirect xattr but missing whiteout to cover lower target,
179 # should fix whiteout
180 echo "+ Missing whiteout"
181 make_test_dirs
182 mkdir $lowerdir/origin
183 make_redirect_dir $upperdir/testdir "origin"
184
185 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
186         echo "fsck should not fail"
187 check_redirect $upperdir/testdir "origin"
188 check_whiteout $upperdir/origin
189
190 # Test valid redirect xattrs exchanged by rename, should not remove
191 echo "+ Valid redirect(3)"
192 make_test_dirs
193 mkdir $lowerdir/{testdir1,testdir2}
194 make_redirect_dir $upperdir/testdir1 "testdir2"
195 make_redirect_dir $upperdir/testdir2 "testdir1"
196
197 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 || \
198         echo "fsck should not fail"
199 check_redirect $upperdir/testdir1 "testdir2"
200 check_redirect $upperdir/testdir2 "testdir1"
201
202 # Test invalid redirect xattr with lower same name directory exists,
203 # should remove invalid redirect xattr and set opaque in yes mode
204 echo "+ Invalid redirect(3)"
205 make_test_dirs
206 mkdir $lowerdir/testdir
207 make_redirect_dir $upperdir/testdir "invalid"
208
209 # Question get yes answer: Should set opaque dir ?
210 _overlay_fsck_dirs $lowerdir $upperdir $workdir -y >> $seqres.full 2>&1 || \
211         echo "fsck should not fail"
212 check_no_redirect $upperdir/testdir
213 check_opaque $upperdir/testdir
214
215 # Test duplicate redirect xattrs point to one origin, should fail in
216 # auto mode, and should remove either of the duplicates in yes mode
217 echo "+ Duplicate redirect"
218 make_test_dirs
219 mkdir $lowerdir2/origin
220 make_redirect_dir $lowerdir/testdir1 "origin"
221 make_redirect_dir $lowerdir/testdir2 "origin"
222 make_redirect_dir $upperdir/testdir3 "origin"
223
224 _overlay_fsck_dirs "$lowerdir:$lowerdir2" $upperdir $workdir -p >> \
225         $seqres.full 2>&1 && echo "fsck should fail"
226
227 # Question get yes answer: Duplicate redirect directory, remove xattr ?
228 _overlay_fsck_dirs "$lowerdir:$lowerdir2" $upperdir $workdir -y >> \
229         $seqres.full 2>&1 || echo "fsck should not fail"
230 redirect_1=`check_redirect $lowerdir/testdir1 "origin" 2>/dev/null`
231 redirect_2=`check_redirect $lowerdir/testdir2 "origin" 2>/dev/null`
232 [[ $redirect_1 == $redirect_2 ]] && echo "Redirect xattr incorrect"
233 check_no_redirect $upperdir/testdir3
234
235 # Test duplicate redirect xattr duplicate with merge directory, should
236 # fail in auto mode, and should remove the redirect xattr in yes mode
237 echo "+ Duplicate redirect(2)"
238 make_test_dirs
239 mkdir $lowerdir/origin $upperdir/origin
240 make_redirect_dir $upperdir/testdir "origin"
241
242 _overlay_fsck_dirs $lowerdir $upperdir $workdir -p >> $seqres.full 2>&1 && \
243         echo "fsck should fail"
244
245 # Question get yes answer: Duplicate redirect directory, remove xattr ?
246 _overlay_fsck_dirs $lowerdir $upperdir $workdir -y >> $seqres.full 2>&1 || \
247         echo "fsck should not fail"
248 check_no_redirect $upperdir/testdir
249
250 # Test duplicate redirect xattr with lower same name directory exists,
251 # should remove the duplicate redirect xattr and set opaque in yes mode
252 echo "+ Duplicate redirect(3)"
253 make_test_dirs
254 mkdir $lowerdir/{origin,testdir} $upperdir/origin
255 make_redirect_dir $upperdir/testdir "invalid"
256
257 # Question one get yes answer: Duplicate redirect directory, remove xattr?
258 # Question two get yes answer: Should set opaque dir ?
259 _overlay_fsck_dirs $lowerdir $upperdir $workdir -y >> $seqres.full 2>&1 || \
260         echo "fsck should not fail"
261 check_no_redirect $upperdir/testdir
262 check_opaque $upperdir/testdir
263
264 # success, all done
265 status=0
266 exit