fstests: use _require_symlinks on all necessary tests
[xfstests-dev.git] / tests / generic / 589
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2019 Red Hat Inc.  All Rights Reserved.
4 #
5 # FS QA Test 589
6 #
7 # Test mount shared subtrees, verify the move semantics:
8 #
9 # ---------------------------------------------------------------------------
10 # |         MOVE MOUNT OPERATION                                            |
11 # |**************************************************************************
12 # |source(A)->| shared       |       private  |       slave    | unbindable |
13 # | dest(B)  |               |                |                |            |
14 # |   |      |               |                |                |            |
15 # |   v      |               |                |                |            |
16 # |**************************************************************************
17 # |  shared  | shared        |     shared     | shared & slave |  invalid   |
18 # |          |               |                |                |            |
19 # |non-shared| shared        |      private   |      slave     | unbindable |
20 # ***************************************************************************
21 #   NOTE: moving a mount residing under a shared mount is invalid.
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         _clear_mount_stack
39         # make sure there's no bug cause dentry isn't be freed
40         rm -rf $MNTHEAD
41 }
42
43 # get standard environment, filters and checks
44 . ./common/rc
45 . ./common/filter
46
47 # remove previous $seqres.full before test
48 rm -f $seqres.full
49
50 # real QA test starts here
51 _supported_fs generic
52 _supported_os Linux
53 _require_test
54 _require_scratch
55 _require_local_device $SCRATCH_DEV
56
57 fs_stress()
58 {
59         local target=$1
60
61         $FSSTRESS_PROG -n 50 -p 3 -d $target >/dev/null
62         sync
63 }
64
65 # prepare some mountpoint dir
66 SRCHEAD=$TEST_DIR/$seq-src
67 DSTHEAD=$TEST_DIR/$seq-dst
68 rm -rf $SRCHEAD $DSTHEAD
69 mkdir $SRCHEAD $DSTHEAD 2>>$seqres.full
70 mpA=$SRCHEAD/"$$"_mpA
71 mpB=$SRCHEAD/"$$"_mpB
72 mpC=$DSTHEAD/"$$"_mpC
73 mpD=$DSTHEAD/"$$"_mpD
74
75 find_mnt()
76 {
77         echo "------"
78         findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \
79                 sed -e "s;$mpA;mpA;g" \
80                     -e "s;$mpB;mpB;g" \
81                     -e "s;$mpC;mpC;g" \
82                     -e "s;$mpD;mpD;g" | \
83                 _filter_spaces | _filter_testdir_and_scratch | sort
84         echo "======"
85 }
86
87 start_test()
88 {
89         local type=$1
90
91         _scratch_mkfs >$seqres.full 2>&1
92
93         _get_mount -t $FSTYP $SCRATCH_DEV $SRCHEAD
94         # make sure $SRCHEAD is private
95         $MOUNT_PROG --make-private $SRCHEAD
96
97         _get_mount -t $FSTYP $SCRATCH_DEV $DSTHEAD
98         # test start with a bind, then make-shared $DSTHEAD
99         _get_mount --bind $DSTHEAD $DSTHEAD
100         $MOUNT_PROG --make-"${type}" $DSTHEAD
101         mkdir $mpA $mpB $mpC $mpD
102 }
103
104 end_test()
105 {
106         _clear_mount_stack
107         rm -rf $mpA $mpB $mpC $mpD
108 }
109
110 move_run()
111 {
112         local source=$1
113         local dest=$2
114
115         start_test $dest
116
117         echo "move $source to $dest"
118         _get_mount -t $FSTYP $SCRATCH_DEV $mpA
119         mkdir -p $mpA/dir 2>/dev/null
120         $MOUNT_PROG --make-shared $mpA
121         # need a peer for slave later
122         _get_mount --bind $mpA $mpB
123         $MOUNT_PROG --make-"$source" $mpB
124         # maybe unbindable at here
125         _get_mount --move $mpB $mpC 2>/dev/null
126         if [ $? -ne 0 ]; then
127                 find_mnt
128                 end_test
129                 return 0
130         fi
131
132         # check mpC after move B to C
133         for m in $mpA $mpC; do
134                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
135                 fs_stress $m/dir
136                 find_mnt
137                 _put_mount
138         done
139
140         # mpC will be in different parent mount, test moving from different
141         # parent mount, and moving a mount residing under a shared mount is
142         # invalid
143         _get_mount --move $mpC $mpD 2>/dev/null
144         if [ $? -ne 0 ]; then
145                 find_mnt
146                 end_test
147                 return 0
148         fi
149         for m in $mpA $mpD; do
150                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
151                 fs_stress $m/dir
152                 find_mnt
153                 _put_mount
154         done
155
156         end_test
157 }
158
159 move_test()
160 {
161         #        source     dest
162         move_run shared     shared
163         move_run slave      shared
164         move_run private    shared
165         move_run unbindable shared
166
167         move_run shared     slave
168         move_run slave      slave
169         move_run private    slave
170         move_run unbindable slave
171
172         move_run shared     private
173         move_run slave      private
174         move_run private    private
175         move_run unbindable private
176 }
177
178 move_test
179
180 # success, all done
181 status=0
182 exit