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