]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-04.bsod.sh
man/systemd.mount: tmpfs automatically gains After=swap.target dep
[thirdparty/systemd.git] / test / units / testsuite-04.bsod.sh
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
5
6 if systemd-detect-virt -cq; then
7 echo "This test requires a VM, skipping the test"
8 exit 0
9 fi
10
11 # shellcheck disable=SC2317
12 at_exit() {
13 local EC=$?
14
15 if [[ $EC -ne 0 ]] && [[ -e /tmp/console.dump ]]; then
16 cat /tmp/console.dump
17 fi
18
19 if mountpoint -q /var/log/journal; then
20 journalctl --relinquish-var
21 umount /var/log/journal
22 journalctl --flush
23 fi
24
25 return 0
26 }
27
28 vcs_dump_and_check() {
29 local expected_message="${1:?}"
30
31 # It might take a while before the systemd-bsod stuff appears on the VCS,
32 # so try it a couple of times
33 for _ in {0..9}; do
34 setterm --term linux --dump --file /tmp/console.dump
35 if grep -aq "Press any key to exit" /tmp/console.dump
36 grep -aq "$expected_message" /tmp/console.dump
37 grep -aq "The current boot has failed" /tmp/console.dump; then
38
39 return 0
40 fi
41
42 sleep .5
43 done
44
45 return 1
46 }
47
48 # Since systemd-bsod always fetches only the first emergency message from the
49 # current boot, let's temporarily overmount /var/log/journal with a tmpfs,
50 # as we're going to wipe it multiple times, but we need to keep the original
51 # journal intact for the other tests to work correctly.
52 trap at_exit EXIT
53 mount -t tmpfs tmpfs /var/log/journal
54 systemctl restart systemd-journald
55
56 systemctl stop systemd-bsod
57
58 # Since we just wiped the journal, there should be no emergency messages and
59 # systemd-bsod should be just a no-op
60 timeout 10s /usr/lib/systemd/systemd-bsod
61 setterm --term linux --dump --file /tmp/console.dump
62 (! grep "The current boot has failed" /tmp/console.dump)
63
64 # systemd-bsod should pick up emergency messages only with UID=0, so let's check
65 # that as well
66 systemd-run --user --machine testuser@ --wait --pipe systemd-cat -p emerg echo "User emergency message"
67 systemd-cat -p emerg echo "Root emergency message"
68 journalctl --sync
69 # Set $SYSTEMD_COLORS so systemd-bsod also prints out the QR code
70 SYSTEMD_COLORS=256 /usr/lib/systemd/systemd-bsod &
71 PID=$!
72 vcs_dump_and_check "Root emergency message"
73 grep -aq "Scan the QR code" /tmp/console.dump
74 # TODO: check if systemd-bsod exits on a key press (didn't figure this one out yet)
75 kill $PID
76 timeout 10 bash -c "while kill -0 $PID; do sleep .5; done"
77
78 # Wipe the journal
79 journalctl --vacuum-size=1 --rotate
80 (! journalctl -q -b -p emerg --grep .)
81
82 # Check the systemd-bsod.service as well
83 # Note: the systemd-bsod.service unit has ConditionVirtualization=no, so let's
84 # temporarily override it just for the test
85 mkdir /run/systemd/system/systemd-bsod.service.d
86 printf '[Unit]\nConditionVirtualization=\n' >/run/systemd/system/systemd-bsod.service.d/99-override.conf
87 systemctl daemon-reload
88 systemctl start systemd-bsod
89 systemd-cat -p emerg echo "Service emergency message"
90 vcs_dump_and_check "Service emergency message"
91 systemctl stop systemd-bsod
92
93 # Wipe the journal
94 journalctl --vacuum-size=1 --rotate
95 (! journalctl -q -b -p emerg --grep .)
96
97 # Same as above, but make sure the service responds to signals even when there are
98 # no "emerg" messages, see systemd/systemd#30084
99 (! systemctl is-active systemd-bsod)
100 systemctl start systemd-bsod
101 timeout 5s bash -xec 'until systemctl is-active systemd-bsod; do sleep .5; done'
102 timeout 5s systemctl stop systemd-bsod
103 timeout 5s bash -xec 'while systemctl is-active systemd-bsod; do sleep .5; done'