]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-60.sh
test: Drop /usr overlay workaround
[thirdparty/systemd.git] / test / units / testsuite-60.sh
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
5
6 # shellcheck source=test/units/util.sh
7 . "$(dirname "$0")"/util.sh
8
9 teardown_test_dependencies() (
10 set +eux
11
12 if mountpoint /tmp/deptest; then
13 umount /tmp/deptest
14 fi
15
16 if [[ -n "${LOOP}" ]]; then
17 losetup -d "${LOOP}" || :
18 fi
19 if [[ -n "${LOOP_0}" ]]; then
20 losetup -d "${LOOP_0}" || :
21 fi
22 if [[ -n "${LOOP_1}" ]]; then
23 losetup -d "${LOOP_1}" || :
24 fi
25
26 rm -f /tmp/testsuite-60-dependencies-0.img
27 rm -f /tmp/testsuite-60-dependencies-1.img
28
29 rm -f /run/systemd/system/tmp-deptest.mount
30 systemctl daemon-reload
31
32 return 0
33 )
34
35 setup_loop() {
36 truncate -s 30m "/tmp/testsuite-60-dependencies-${1?}.img"
37 sfdisk --wipe=always "/tmp/testsuite-60-dependencies-${1?}.img" <<EOF
38 label:gpt
39
40 name="loop${1?}-part1"
41 EOF
42 LOOP=$(losetup -P --show -f "/tmp/testsuite-60-dependencies-${1?}.img")
43 udevadm wait --settle --timeout=10 "${LOOP}"
44 udevadm lock --device="${LOOP}" mkfs.ext4 -L "partname${1?}-1" "${LOOP}p1"
45 }
46
47 check_dependencies() {
48 local escaped_0 escaped_1 after
49
50 escaped_0=$(systemd-escape -p "${LOOP_0}p1")
51 escaped_1=$(systemd-escape -p "${LOOP_1}p1")
52
53 if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
54 after=$(systemctl show --property=After --value tmp-deptest.mount)
55 assert_not_in "local-fs-pre.target" "$after"
56 assert_in "remote-fs-pre.target" "$after"
57 assert_in "network.target" "$after"
58 fi
59
60 # mount LOOP_0
61 mount -t ext4 "${LOOP_0}p1" /tmp/deptest
62 sleep 1
63 after=$(systemctl show --property=After --value tmp-deptest.mount)
64 assert_in "local-fs-pre.target" "$after"
65 assert_not_in "remote-fs-pre.target" "$after"
66 assert_not_in "network.target" "$after"
67 assert_in "${escaped_0}.device" "$after"
68 assert_in "blockdev@${escaped_0}.target" "$after"
69 assert_not_in "${escaped_1}.device" "$after"
70 assert_not_in "blockdev@${escaped_1}.target" "$after"
71 umount /tmp/deptest
72
73 if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
74 after=$(systemctl show --property=After --value tmp-deptest.mount)
75 assert_not_in "local-fs-pre.target" "$after"
76 assert_in "remote-fs-pre.target" "$after"
77 assert_in "network.target" "$after"
78 fi
79
80 # mount LOOP_1 (using fake _netdev option)
81 mount -t ext4 -o _netdev "${LOOP_1}p1" /tmp/deptest
82 sleep 1
83 after=$(systemctl show --property=After --value tmp-deptest.mount)
84 assert_not_in "local-fs-pre.target" "$after"
85 assert_in "remote-fs-pre.target" "$after"
86 assert_in "network.target" "$after"
87 assert_not_in "${escaped_0}.device" "$after"
88 assert_not_in "blockdev@${escaped_0}.target" "$after"
89 assert_in "${escaped_1}.device" "$after"
90 assert_in "blockdev@${escaped_1}.target" "$after"
91 umount /tmp/deptest
92
93 if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
94 after=$(systemctl show --property=After --value tmp-deptest.mount)
95 assert_not_in "local-fs-pre.target" "$after"
96 assert_in "remote-fs-pre.target" "$after"
97 assert_in "network.target" "$after"
98 fi
99
100 # mount tmpfs
101 mount -t tmpfs tmpfs /tmp/deptest
102 sleep 1
103 after=$(systemctl show --property=After --value tmp-deptest.mount)
104 assert_in "local-fs-pre.target" "$after"
105 assert_not_in "remote-fs-pre.target" "$after"
106 assert_not_in "network.target" "$after"
107 assert_not_in "${escaped_0}.device" "$after"
108 assert_not_in "blockdev@${escaped_0}.target" "$after"
109 assert_not_in "${escaped_1}.device" "$after"
110 assert_not_in "blockdev@${escaped_1}.target" "$after"
111 umount /tmp/deptest
112
113 if [[ -f /run/systemd/system/tmp-deptest.mount ]]; then
114 after=$(systemctl show --property=After --value tmp-deptest.mount)
115 assert_not_in "local-fs-pre.target" "$after"
116 assert_in "remote-fs-pre.target" "$after"
117 assert_in "network.target" "$after"
118 fi
119 }
120
121 test_dependencies() {
122 if systemd-detect-virt --quiet --container; then
123 echo "Skipping test_dependencies in container"
124 return
125 fi
126
127 trap teardown_test_dependencies RETURN
128
129 setup_loop 0
130 LOOP_0="${LOOP}"
131 LOOP=
132 setup_loop 1
133 LOOP_1="${LOOP}"
134 LOOP=
135
136 mkdir -p /tmp/deptest
137
138 # without .mount file
139 check_dependencies
140
141 # create .mount file
142 mkdir -p /run/systemd/system
143 cat >/run/systemd/system/tmp-deptest.mount <<EOF
144 [Mount]
145 Where=/tmp/deptest
146 What=192.168.0.1:/tmp/mnt
147 Type=nfs
148 EOF
149 systemctl daemon-reload
150
151 # with .mount file
152 check_dependencies
153 }
154
155 test_issue_20329() {
156 local tmpdir unit
157 tmpdir="$(mktemp -d)"
158 unit=$(systemd-escape --suffix mount --path "$tmpdir")
159
160 # Set up test mount unit
161 cat >/run/systemd/system/"$unit" <<EOF
162 [Mount]
163 What=tmpfs
164 Where=$tmpdir
165 Type=tmpfs
166 Options=defaults,nofail
167 EOF
168
169 # Start the unit
170 systemctl daemon-reload
171 systemctl start "$unit"
172
173 [[ "$(systemctl show --property SubState --value "$unit")" = "mounted" ]] || {
174 echo >&2 "Test mount \"$unit\" unit isn't mounted"
175 return 1
176 }
177 mountpoint -q "$tmpdir"
178
179 trap 'systemctl stop $unit' RETURN
180
181 # Trigger the mount ratelimiting
182 cd "$(mktemp -d)"
183 mkdir foo
184 for _ in {1..50}; do
185 mount --bind foo foo
186 umount foo
187 done
188
189 # Unmount the test mount and start it immediately again via systemd
190 umount "$tmpdir"
191 systemctl start "$unit"
192
193 # Make sure it is seen as mounted by systemd and it actually is mounted
194 [[ "$(systemctl show --property SubState --value "$unit")" = "mounted" ]] || {
195 echo >&2 "Test mount \"$unit\" unit isn't in \"mounted\" state"
196 return 1
197 }
198
199 mountpoint -q "$tmpdir" || {
200 echo >&2 "Test mount \"$unit\" is in \"mounted\" state, actually is not mounted"
201 return 1
202 }
203 }
204
205 test_issue_23796() {
206 local mount_path mount_mytmpfs
207
208 mount_path="$(command -v mount 2>/dev/null)"
209 mount_mytmpfs="${mount_path/\/bin/\/sbin}.mytmpfs"
210 cat >"$mount_mytmpfs" <<EOF
211 #!/bin/bash
212 sleep ".\$RANDOM"
213 exec -- $mount_path -t tmpfs tmpfs "\$2"
214 EOF
215 chmod +x "$mount_mytmpfs"
216
217 mkdir -p /run/systemd/system
218 cat >/run/systemd/system/tmp-hoge.mount <<EOF
219 [Mount]
220 What=mytmpfs
221 Where=/tmp/hoge
222 Type=mytmpfs
223 EOF
224
225 # shellcheck disable=SC2064
226 trap "rm -f /run/systemd/system/tmp-hoge.mount '$mount_mytmpfs'" RETURN
227
228 for _ in {1..10}; do
229 systemctl --no-block start tmp-hoge.mount
230 sleep ".$RANDOM"
231 systemctl daemon-reexec
232
233 sleep 1
234
235 if [[ "$(systemctl is-failed tmp-hoge.mount)" == "failed" ]] || \
236 journalctl -u tmp-hoge.mount -q --grep "but there is no mount"; then
237 exit 1
238 fi
239
240 systemctl stop tmp-hoge.mount
241 done
242 }
243
244 systemd-analyze log-level debug
245 systemd-analyze log-target journal
246
247 NUM_DIRS=20
248
249 # make sure we can handle mounts at very long paths such that mount unit name must be hashed to fall within our unit name limit
250 LONGPATH="$(printf "/$(printf "x%0.s" {1..255})%0.s" {1..7})"
251 LONGMNT="$(systemd-escape --suffix=mount --path "$LONGPATH")"
252 TS="$(date '+%H:%M:%S')"
253
254 mkdir -p "$LONGPATH"
255 mount -t tmpfs tmpfs "$LONGPATH"
256 systemctl daemon-reload
257
258 # check that unit is active(mounted)
259 systemctl --no-pager show -p SubState --value "$LONGPATH" | grep -q mounted
260
261 # check that relevant part of journal doesn't contain any errors related to unit
262 [ "$(journalctl -b --since="$TS" --priority=err | grep -c "$LONGMNT")" = "0" ]
263
264 # check that we can successfully stop the mount unit
265 systemctl stop "$LONGPATH"
266 rm -rf "$LONGPATH"
267
268 # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting
269
270 for ((i = 0; i < NUM_DIRS; i++)); do
271 mkdir "/tmp/meow${i}"
272 done
273
274 TS="$(date '+%H:%M:%S')"
275
276 for ((i = 0; i < NUM_DIRS; i++)); do
277 mount -t tmpfs tmpfs "/tmp/meow${i}"
278 done
279
280 systemctl daemon-reload
281 systemctl list-units -t mount tmp-meow* | grep -q tmp-meow
282
283 for ((i = 0; i < NUM_DIRS; i++)); do
284 umount "/tmp/meow${i}"
285 done
286
287 # Figure out if we have entered the rate limit state.
288 # If the infra is slow we might not enter the rate limit state; in that case skip the exit check.
289 if timeout 2m bash -c "until journalctl -u init.scope --since=$TS | grep -q '(mount-monitor-dispatch) entered rate limit'; do sleep 1; done"; then
290 timeout 2m bash -c "until journalctl -u init.scope --since=$TS | grep -q '(mount-monitor-dispatch) left rate limit'; do sleep 1; done"
291 fi
292
293 # Verify that the mount units are always cleaned up at the end.
294 # Give some time for units to settle so we don't race between exiting the rate limit state and cleaning up the units.
295 timeout 2m bash -c 'while systemctl list-units -t mount tmp-meow* | grep -q tmp-meow; do systemctl daemon-reload; sleep 10; done'
296
297 # test for issue #19983 and #23552.
298 test_dependencies
299
300 # test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited
301 test_issue_20329
302
303 # test for reexecuting with background mount job
304 test_issue_23796
305
306 systemd-analyze log-level info
307
308 touch /testok