2 # SPDX-License-Identifier: LGPL-2.1-or-later
6 # shellcheck source=test/units/util.sh
7 .
"$(dirname "$0")"/util.sh
9 teardown_test_dependencies
() (
12 if mountpoint
/tmp
/deptest
; then
16 if [[ -n "${LOOP}" ]]; then
17 losetup
-d "${LOOP}" ||
:
19 if [[ -n "${LOOP_0}" ]]; then
20 losetup
-d "${LOOP_0}" ||
:
22 if [[ -n "${LOOP_1}" ]]; then
23 losetup
-d "${LOOP_1}" ||
:
26 rm -f /tmp
/testsuite-60-dependencies-0.img
27 rm -f /tmp
/testsuite-60-dependencies-1.img
29 rm -f /run
/systemd
/system
/tmp-deptest.mount
30 systemctl daemon-reload
36 truncate
-s 30m
"/tmp/testsuite-60-dependencies-${1?}.img"
37 sfdisk
--wipe=always
"/tmp/testsuite-60-dependencies-${1?}.img" <<EOF
40 name="loop${1?}-part1"
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"
47 check_dependencies
() {
48 local escaped_0 escaped_1 after
50 escaped_0
=$
(systemd-escape
-p "${LOOP_0}p1")
51 escaped_1
=$
(systemd-escape
-p "${LOOP_1}p1")
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"
61 mount
-t ext4
"${LOOP_0}p1" /tmp
/deptest
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"
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"
80 # mount LOOP_1 (using fake _netdev option)
81 mount
-t ext4
-o _netdev
"${LOOP_1}p1" /tmp
/deptest
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"
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"
101 mount
-t tmpfs tmpfs
/tmp
/deptest
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"
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"
121 test_dependencies
() {
122 if systemd-detect-virt
--quiet --container; then
123 echo "Skipping test_dependencies in container"
127 trap teardown_test_dependencies RETURN
136 mkdir
-p /tmp
/deptest
138 # without .mount file
142 mkdir
-p /run
/systemd
/system
143 cat >/run
/systemd
/system
/tmp-deptest.mount
<<EOF
146 What=192.168.0.1:/tmp/mnt
149 systemctl daemon-reload
157 tmpdir
="$(mktemp -d)"
158 unit
=$
(systemd-escape
--suffix mount
--path "$tmpdir")
160 # Set up test mount unit
161 cat >/run
/systemd
/system
/"$unit" <<EOF
166 Options=defaults,nofail
170 systemctl daemon-reload
171 systemctl start
"$unit"
173 [[ "$(systemctl show --property SubState --value "$unit")" = "mounted" ]] ||
{
174 echo >&2 "Test mount \"$unit\" unit isn't mounted"
177 mountpoint
-q "$tmpdir"
179 trap 'systemctl stop $unit' RETURN
181 # Trigger the mount ratelimiting
189 # Unmount the test mount and start it immediately again via systemd
191 systemctl start
"$unit"
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"
199 mountpoint
-q "$tmpdir" ||
{
200 echo >&2 "Test mount \"$unit\" is in \"mounted\" state, actually is not mounted"
206 local mount_path mount_mytmpfs
208 mount_path
="$(command -v mount 2>/dev/null)"
209 mount_mytmpfs
="${mount_path/\/bin/\/sbin}.mytmpfs"
210 cat >"$mount_mytmpfs" <<EOF
213 exec -- $mount_path -t tmpfs tmpfs "\$2"
215 chmod +x
"$mount_mytmpfs"
217 mkdir
-p /run
/systemd
/system
218 cat >/run
/systemd
/system
/tmp-hoge.mount
<<EOF
225 # shellcheck disable=SC2064
226 trap "rm -f /run/systemd/system/tmp-hoge.mount '$mount_mytmpfs'" RETURN
229 systemctl
--no-block start tmp-hoge.mount
231 systemctl daemon-reexec
235 if [[ "$(systemctl is-failed tmp-hoge.mount)" == "failed" ]] || \
236 journalctl
-u tmp-hoge.mount
-q --grep "but there is no mount"; then
240 systemctl stop tmp-hoge.mount
244 systemd-analyze log-level debug
245 systemd-analyze log-target journal
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')"
255 mount
-t tmpfs tmpfs
"$LONGPATH"
256 systemctl daemon-reload
258 # check that unit is active(mounted)
259 systemctl
--no-pager show
-p SubState
--value "$LONGPATH" |
grep -q mounted
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" ]
264 # check that we can successfully stop the mount unit
265 systemctl stop
"$LONGPATH"
268 # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting
270 for ((i
= 0; i
< NUM_DIRS
; i
++)); do
271 mkdir
"/tmp/meow${i}"
274 TS
="$(date '+%H:%M:%S')"
276 for ((i
= 0; i
< NUM_DIRS
; i
++)); do
277 mount
-t tmpfs tmpfs
"/tmp/meow${i}"
280 systemctl daemon-reload
281 systemctl list-units
-t mount tmp-meow
* |
grep -q tmp-meow
283 for ((i
= 0; i
< NUM_DIRS
; i
++)); do
284 umount
"/tmp/meow${i}"
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"
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'
297 # test for issue #19983 and #23552.
300 # test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited
303 # test for reexecuting with background mount job
306 systemd-analyze log-level info