a56bbdec5ce6d4f2520199363560e31fb41f230d
[xfstests-dev.git] / tests / xfs / 189
1 #! /bin/bash
2 # FS QA Test No. 189
3 #
4 # Test remount behaviour
5 # Initial motivation was for pv#985710 and pv#983964
6 #
7 # mount(8) adds all options from mtab and fstab to the mount command line.  So
8 # the filesystem either must not reject any option at all if it can't change it,
9 # or compare the value on the command line to the existing state and only reject
10 # it if it would change something that can't be changed.
11 #
12 # Test this behaviour by mounting a filesystem read-only with a non- default
13 # option and then try to remount it rw.
14 #
15 # note that mount(8) doesn't add the options when specifying both the device
16 # node and mount point, so test out the various mounting alternatives
17 #
18 # <---- Bbbzzzzzzztttt ---->
19 #
20 # Right, but the kernel /proc/mounts output in no way reflects what mount passes
21 # into the kernel, so the entire assumption of this test that what mount outputs
22 # is the same as what it inputs is completely wrong.
23 #
24 # Hence the test now checks to see if the expected options are in the mount
25 # options in /etc/mtab rather than looking for an exact match. Hence the tests
26 # check what we know should change, not what mount thinks has changed. As a
27 # result, the test now passes regardless of whether mount or the kernel controls
28 # the contents of /etc/mtab....
29 #
30 # <---- Normal programming is resumed ---->
31 #
32 #
33 #-----------------------------------------------------------------------
34 # Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
35 #
36 # This program is free software; you can redistribute it and/or
37 # modify it under the terms of the GNU General Public License as
38 # published by the Free Software Foundation.
39 #
40 # This program is distributed in the hope that it would be useful,
41 # but WITHOUT ANY WARRANTY; without even the implied warranty of
42 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43 # GNU General Public License for more details.
44 #
45 # You should have received a copy of the GNU General Public License
46 # along with this program; if not, write the Free Software Foundation,
47 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
48 #
49 #-----------------------------------------------------------------------
50 #
51
52 seq=`basename $0`
53 seqres=$RESULT_DIR/$seq
54 echo "QA output created by $seq"
55
56 here=`pwd`
57 tmp=/tmp/$$
58 status=1        # failure is the default!
59 trap "_cleanup; exit \$status" 0 1 2 3 15
60 tag="added by qa $seq"
61
62 rm -f $seqres.full
63
64 _cleanup()
65 {
66         cd /
67         umount $SCRATCH_MNT 2>/dev/null
68         _putback_scratch_fstab
69         rm -f $tmp.*
70 }
71
72 _scratch_filter()
73 {
74         sed -e "s#$SCRATCH_DEV#SCRATCH_DEV#" \
75             -e "s#$SCRATCH_MNT#SCRATCH_MNT#" \
76             -e "s#,context.*s0\"##"
77 }
78
79 #
80 # the output from /proc/mounts in no way matches what mount puts into the kernel
81 # as options. Work around it as best possible by matching the strings passed in
82 # rather than assuming they are the only options that will be set. If they match
83 # output them to the output file so that the golden image and the filtering
84 # doesn't need to care about what options may or may not be present in /etc/mtab
85 #
86 _check_mount()
87 {
88         rw_or_ro=$1
89         expected_val=$2
90
91         [ -z "$expected_val" ] && expected_val=$1
92
93         _mount | grep $SCRATCH_MNT | _scratch_filter | \
94                 tee -a $seqres.full |
95                 grep $rw_or_ro | grep $expected_val > /dev/null
96         if [ $? -eq 0 ]; then
97                 echo -n "SCRATCH_DEV on SCRATCH_MNT type xfs ($rw_or_ro"
98                 if [ ! -z "$2" ]; then
99                         echo -n ",$2"
100                 fi
101                 echo ")"
102         fi
103 }
104
105 _test_remount_rw()
106 {
107         # use filestreams as a hopefully never default option
108         echo
109         echo "try remount ro,filestreams -> rw,filestreams"
110         echo
111         _scratch_mount -o ro,filestreams
112         [ $? -eq 0 ] || echo "ro,filestreams mount failed unexpectedly"
113         _check_mount ro filestreams
114
115         for dev_mnt in $SCRATCH_DEV $SCRATCH_MNT "$SCRATCH_DEV $SCRATCH_MNT"; do
116                 echo "mounting given: $dev_mnt" | _scratch_filter
117                 _mount -o remount,rw,filestreams $dev_mnt
118                 [ $? -eq 0 ] || echo "remount rw failed"
119                 _check_mount rw filestreams
120         done
121
122         umount $SCRATCH_MNT
123
124         # remount ignores attr2, and noattr2 mount option does does not result
125         # in any "attr2" specific option in /proc/mounts, so we can only check
126         # for ro/rw here.
127         echo
128         echo "try remount ro,noattr2 -> rw,attr2"
129         echo
130         _scratch_mount -o ro,noattr2
131         [ $? -eq 0 ] || echo "ro,noattr2 mount failed unexpectedly"
132         _check_mount ro
133
134         for dev_mnt in $SCRATCH_DEV $SCRATCH_MNT "$SCRATCH_DEV $SCRATCH_MNT"; do
135                 echo "mounting given: $dev_mnt" | _scratch_filter
136                 _mount -o remount,rw,attr2 $dev_mnt
137                 [ $? -eq 0 ] || echo "remount rw,attr2 failed"
138                 _check_mount rw
139         done
140
141         umount $SCRATCH_MNT
142 }
143
144 #
145 # make sure we really can write to a filesystem after remount,rw
146 #
147 _test_remount_write()
148 {
149         echo
150         echo "try touching file after remount ro -> rw with options"
151         echo
152         _scratch_mount
153         [ $? -eq 0 ] || echo "mount (1) failed unexpectedly"
154
155         touch $SCRATCH_MNT/foobar
156         [ $? -eq 0 ] || echo "touch (1) failed unexpectedly"
157
158         umount $SCRATCH_MNT
159
160         _scratch_mount -o ro
161         [ $? -eq 0 ] || echo "mount (2) failed unexpectedly"
162
163         _mount -o remount,rw,filestreams $SCRATCH_MNT
164         [ $? -eq 0 ] || echo "remount failed unexpectedly"
165
166         touch $SCRATCH_MNT/foobar
167         [ $? -eq 0 ] || echo "touch (2) failed unexpectedly"
168
169         umount $SCRATCH_MNT
170 }
171
172 #
173 # barrier is the only option we can change besides ro<->rw which is partially
174 # handled by the VFS and tested elsewhere.  Make sure mount accepts going
175 # from barrier (which also is the default) to nobarrier and back.
176 #
177 _test_remount_barrier()
178 {
179         echo
180         echo "Do remount barrier tests"
181         echo
182
183         # mention barrier explicitly even if it's currently the default just to be sure
184         _scratch_mount -o barrier
185         [ $? -eq 0 ] || echo "mount failed unexpectedly!"
186         _check_mount rw
187
188         _scratch_mount -o remount,nobarrier
189         [ $? -eq 0 ] || _fail "remount nobarrier failed"
190         _check_mount rw nobarrier
191
192         _scratch_mount -o remount,barrier
193         [ $? -eq 0 ] || _fail "remount barrier failed"
194         _check_mount rw
195
196         umount $SCRATCH_MNT
197 }
198
199 #
200 # Example fstab entry
201 # /dev/sdb2            /mnt/scratch1        xfs       defaults 0 0
202 #
203 _add_scratch_fstab()
204 {
205         # comment out any existing SCRATCH_DEV
206         $SED_PROG -i "s;$SCRATCH_DEV;#$SCRATCH_DEV;" /etc/fstab
207
208         # add our fstab entry
209         echo "$SCRATCH_DEV $SCRATCH_MNT xfs defaults 0 0 # $tag" >> /etc/fstab
210 }
211
212 _modify_scratch_fstab()
213 {
214         opts=$1
215
216         # modify our fstab entry that we added
217         # modify opts by looking for last word which has non-space chars
218         $SED_PROG -i "s; [^ ]* 0 0 # $tag; $opts 0 0 # $tag;" /etc/fstab
219 }
220
221 _putback_scratch_fstab()
222 {
223         # uncomment out any existing SCRATCH_DEV
224         $SED_PROG -i "s;#$SCRATCH_DEV;$SCRATCH_DEV;" /etc/fstab
225
226         # remove the one we added at the end
227         $SED_PROG -i "/# $tag/d" /etc/fstab
228 }
229
230 # get standard environment, filters and checks
231 . ./common/rc
232 . ./common/filter
233 . ./common/attr
234
235 # real QA test starts here
236 _supported_fs xfs
237 _supported_os Linux
238
239 _need_to_be_root
240 _require_scratch
241 _require_noattr2
242
243 unset SCRATCH_RTDEV
244 unset SCRATCH_LOGDEV
245
246 _scratch_mkfs_xfs | _filter_mkfs 2>/dev/null
247
248 _add_scratch_fstab
249 _test_remount_rw
250 _test_remount_write
251
252 echo
253 echo "add noikeep to fstab for scratch"
254 _modify_scratch_fstab noikeep # noikeep is not default for non dmapi
255 _test_remount_rw
256
257 _putback_scratch_fstab
258 _test_remount_barrier
259
260 # success, all done
261 echo "*** done"
262 status=0