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