misc: move exit status into trap handler
[xfstests-dev.git] / tests / generic / 409
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2016 Red Hat Inc.  All Rights Reserved.
4 #
5 # FS QA Test 409
6 #
7 # Test mount shared subtrees, verify the bind semantics:
8 #
9 # ---------------------------------------------------------------------------
10 # |         BIND 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     |  invalid   |
20 # ***************************************************************************
21 #
22 seq=`basename $0`
23 seqres=$RESULT_DIR/$seq
24 echo "QA output created by $seq"
25
26 here=`pwd`
27 tmp=/tmp/$$
28 status=1        # failure is the default!
29 trap "_cleanup; exit \$status" 0 1 2 3 15
30
31 _cleanup()
32 {
33         cd /
34         rm -f $tmp.*
35         _clear_mount_stack
36         # make sure there's no bug cause dentry isn't be freed
37         rm -rf $MNTHEAD
38 }
39
40 # get standard environment, filters and checks
41 . ./common/rc
42 . ./common/filter
43
44 # remove previous $seqres.full before test
45 rm -f $seqres.full
46
47 # real QA test starts here
48 _supported_fs generic
49 _require_test
50 _require_scratch
51 _require_local_device $SCRATCH_DEV
52
53 fs_stress()
54 {
55         local target=$1
56
57         $FSSTRESS_PROG -z -n 50 -p 3 \
58                        -f creat=5 \
59                        -f mkdir=5 \
60                        -f link=2 \
61                        -f rename=1 \
62                        -f rmdir=2 \
63                        -f unlink=1 \
64                        -f symlink=1 \
65                        -f write=1 \
66                        -f read=1 \
67                        -f chown=1 \
68                        -f getdents=1 \
69                        -f fiemap=1 \
70                        -d $target >/dev/null
71         sync
72 }
73
74 # prepare some mountpoint dir
75 MNTHEAD=$TEST_DIR/$seq
76 rm -rf $MNTHEAD
77 mkdir $MNTHEAD 2>>$seqres.full
78 mpA=$MNTHEAD/"$$"_mpA
79 mpB=$MNTHEAD/"$$"_mpB
80 mpC=$MNTHEAD/"$$"_mpC
81 mpD=$MNTHEAD/"$$"_mpD
82
83 find_mnt()
84 {
85         echo "------"
86         findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \
87                 sed -e "s;$mpA;mpA;g" \
88                     -e "s;$mpB;mpB;g" \
89                     -e "s;$mpC;mpC;g" \
90                     -e "s;$mpD;mpD;g" | \
91                 _filter_spaces | _filter_testdir_and_scratch | sort
92         echo "======"
93 }
94
95 start_test()
96 {
97         local type=$1
98
99         _scratch_mkfs >$seqres.full 2>&1
100         _get_mount -t $FSTYP $SCRATCH_DEV $MNTHEAD
101         $MOUNT_PROG --make-"${type}" $MNTHEAD
102         mkdir $mpA $mpB $mpC $mpD
103 }
104
105 end_test()
106 {
107         _clear_mount_stack
108         rm -rf $mpA $mpB $mpC $mpD
109 }
110
111 bind_run()
112 {
113         local source=$1
114         local dest=$2
115
116         start_test $dest
117
118         echo "bind $source on $dest"
119         _get_mount -t $FSTYP $SCRATCH_DEV $mpA
120         mkdir -p $mpA/dir 2>/dev/null
121         $MOUNT_PROG --make-shared $mpA
122         _get_mount --bind $mpA $mpB
123         $MOUNT_PROG --make-"$source" $mpB
124         # maybe unbindable at here
125         _get_mount --bind $mpB $mpC 2>/dev/null
126         if [ $? -ne 0 ]; then
127                 find_mnt
128                 end_test
129                 return 0
130         fi
131         _get_mount --bind $mpC $mpD
132         for m in $mpA $mpB $mpC $mpD; do
133                 _get_mount -t $FSTYP $SCRATCH_DEV $m/dir
134                 fs_stress $m/dir
135                 find_mnt
136                 _put_mount
137         done
138
139         end_test
140 }
141
142 bind_test()
143 {
144         #        source     dest
145         bind_run shared     shared
146         bind_run slave      shared
147         bind_run private    shared
148         bind_run unbindable shared
149
150         bind_run shared     slave
151         bind_run slave      slave
152         bind_run private    slave
153         bind_run unbindable slave
154
155         bind_run shared     private
156         bind_run slave      private
157         bind_run private    private
158         bind_run unbindable private
159 }
160
161 bind_test
162
163 # success, all done
164 status=0
165 exit