Stop the boot from waiting on a black screen for the console to answer
About 1 boot in 10 of an installed system stops on a black screen at
"Starting Switch Root" until a key is pressed. systemd 257 and later
asks the console for its size with ANSI escape sequences when PID 1
starts and waits for the reply; with Plymouth holding the VT the reply
sometimes never comes.
Measured in QEMU on repeated boots of one install: 3 hangs in 30 and 1
in 40 on the prebuilt UKI, 7 in 40 on the stock initramfs, every one of
them ended by pressing Enter; none in 40 with a serial console, none in
40 with plymouth.enable=0, and none in 80 with
systemd.tty.term.console=dumb, which makes systemd skip the query.
systemd fixed two variants of this in v261; Arch's 261.2 still shows it.
The parameter goes where the last Plymouth boot fix went (3f725531,
initramfs_async=0): into the packaged omarchy-defaults.conf for fresh
installs, and a migration rebuilds the boot image on existing systems,
once per machine, only where the booted command line lacks it. Nothing
visible changes under "quiet splash".
Refs #2931
This commit is contained in:
1 parent
2519fd9a97
commit
f03bf06742
4 files changed
+110
No files matched your search
@@ -9,6 +9,15 @@ KERNEL_CMDLINE[default]+=" quiet splash loglevel=0 systemd.show_status=false rd.
|
||||
# is fixed upstream.
|
||||
KERNEL_CMDLINE[default]+=" initramfs_async=0"
|
||||
|
||||
# systemd 257 and later asks the console for its size with ANSI escape
|
||||
# sequences when PID 1 starts, and waits for the reply. With Plymouth holding
|
||||
# the VT the reply sometimes never comes, and the boot sits on a black screen
|
||||
# at "Starting Switch Root" until a key is pressed: about 1 boot in 10. A dumb
|
||||
# $TERM for the console makes systemd skip the query. Nothing visible changes
|
||||
# under "quiet splash". Drop it once a systemd release boots clean in a
|
||||
# repeated boot test.
|
||||
KERNEL_CMDLINE[default]+=" systemd.tty.term.console=dumb"
|
||||
|
||||
CUSTOM_UKI_NAME="omarchy"
|
||||
ENABLE_LIMINE_FALLBACK=yes
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
echo "Stop the boot from waiting on a black screen for the console to answer"
|
||||
|
||||
# systemd asks the console for its size when PID 1 starts and waits for the
|
||||
# reply. With Plymouth holding the screen the reply sometimes never comes, and
|
||||
# about 1 boot in 10 sits on a black screen until a key is pressed.
|
||||
# omarchy-defaults.conf now carries systemd.tty.term.console=dumb, which makes
|
||||
# systemd skip the query. The package has already written that file by the
|
||||
# time this runs; the boot image still holds the old command line until it is
|
||||
# rebuilt.
|
||||
|
||||
defaults_conf="${OMARCHY_LIMINE_DEFAULTS_CONF:-/etc/limine-entry-tool.d/omarchy-defaults.conf}"
|
||||
running_cmdline="${OMARCHY_RUNNING_CMDLINE:-/proc/cmdline}"
|
||||
rebuild_marker="${OMARCHY_LIMINE_REBUILD_MARKER:-/var/lib/omarchy/migrations/1791581004}"
|
||||
param="systemd.tty.term.console=dumb"
|
||||
|
||||
omarchy-cmd-present limine-mkinitcpio || exit 0
|
||||
[[ -f $defaults_conf && -r $running_cmdline ]] || exit 0
|
||||
|
||||
# The running kernel keeps its old command line until reboot, so a marker
|
||||
# records the machine-wide rebuild: another user's migration must not repeat
|
||||
# it before then, while a missing marker still retries an interrupted rebuild.
|
||||
[[ ! -e $rebuild_marker ]] || exit 0
|
||||
|
||||
# A machine that boots with it already, or whose defaults were edited to leave
|
||||
# it out, has nothing to rebuild.
|
||||
[[ " $(<"$running_cmdline") " != *" $param "* ]] || exit 0
|
||||
grep -Eq "^KERNEL_CMDLINE\[default\]\+=\".*${param//./\\.}.*\"" "$defaults_conf" || exit 0
|
||||
|
||||
echo "The booted kernel is missing $param; rebuilding the boot image"
|
||||
sudo limine-mkinitcpio
|
||||
sudo install -Dm644 /dev/null "$rebuild_marker"
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# The migration that puts systemd.tty.term.console=dumb into effect on an
|
||||
# existing install: the package has already written the parameter into
|
||||
# omarchy-defaults.conf, so what is left is rebuilding the boot image, once per
|
||||
# machine, and only where it is needed.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
|
||||
|
||||
migration="$ROOT/migrations/1791581004.sh"
|
||||
test_dir=$(mktemp -d)
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
stub_bin="$test_dir/bin"
|
||||
mkdir -p "$stub_bin"
|
||||
|
||||
# sudo just drops the prefix; limine-mkinitcpio records that it ran.
|
||||
printf '#!/bin/bash\nexec "$@"\n' >"$stub_bin/sudo"
|
||||
printf '#!/bin/bash\necho rebuilt >>"${REBUILDS:?}"\n' >"$stub_bin/limine-mkinitcpio"
|
||||
chmod +x "$stub_bin"/*
|
||||
|
||||
old_cmdline="root=PARTUUID=1 rw quiet splash initramfs_async=0"
|
||||
new_cmdline="$old_cmdline systemd.tty.term.console=dumb"
|
||||
|
||||
run() { # booted cmdline, defaults conf
|
||||
: >"$test_dir/rebuilds"
|
||||
printf '%s\n' "$1" >"$test_dir/cmdline"
|
||||
PATH="$stub_bin:$ROOT/bin:$PATH" REBUILDS="$test_dir/rebuilds" \
|
||||
OMARCHY_RUNNING_CMDLINE="$test_dir/cmdline" OMARCHY_LIMINE_DEFAULTS_CONF="$2" \
|
||||
OMARCHY_LIMINE_REBUILD_MARKER="$test_dir/marker" bash "$migration" >/dev/null
|
||||
}
|
||||
rebuilds() { wc -l <"$test_dir/rebuilds"; }
|
||||
|
||||
run "$old_cmdline" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"
|
||||
[[ $(rebuilds) == 1 && -e $test_dir/marker ]] ||
|
||||
fail "a machine booted without the parameter did not get its boot image rebuilt"
|
||||
pass "a machine booted without the parameter gets its boot image rebuilt, with the packaged defaults"
|
||||
|
||||
run "$old_cmdline" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"
|
||||
[[ $(rebuilds) == 0 ]] || fail "the rebuild ran a second time before a reboot"
|
||||
pass "the rebuild runs once per machine, not once per user"
|
||||
|
||||
rm -f "$test_dir/marker"
|
||||
run "$new_cmdline" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"
|
||||
[[ $(rebuilds) == 0 && ! -e $test_dir/marker ]] || fail "a machine that already boots with the parameter was rebuilt"
|
||||
pass "a machine that already boots with the parameter is left alone"
|
||||
|
||||
grep -v "tty.term.console" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf" >"$test_dir/edited.conf"
|
||||
run "$old_cmdline" "$test_dir/edited.conf"
|
||||
[[ $(rebuilds) == 0 ]] || fail "a machine whose defaults leave the parameter out was rebuilt anyway"
|
||||
pass "a machine whose defaults were edited to leave the parameter out is left alone"
|
||||
|
||||
# No Limine: the stand-in goes, and the PATH holds only what the migration
|
||||
# needs, so a limine-mkinitcpio installed on the machine running this test is
|
||||
# not found either.
|
||||
rm "$stub_bin/limine-mkinitcpio"
|
||||
mkdir -p "$test_dir/tools"
|
||||
for tool in bash grep install cat; do ln -s "$(command -v "$tool")" "$test_dir/tools/$tool"; done
|
||||
: >"$test_dir/rebuilds"
|
||||
printf '%s\n' "$old_cmdline" >"$test_dir/cmdline"
|
||||
PATH="$stub_bin:$ROOT/bin:$test_dir/tools" REBUILDS="$test_dir/rebuilds" \
|
||||
OMARCHY_RUNNING_CMDLINE="$test_dir/cmdline" OMARCHY_LIMINE_DEFAULTS_CONF="$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf" \
|
||||
OMARCHY_LIMINE_REBUILD_MARKER="$test_dir/marker" "$test_dir/tools/bash" "$migration" >/dev/null
|
||||
[[ ! -e $test_dir/marker ]] || fail "a machine without Limine was marked as rebuilt"
|
||||
pass "a machine without Limine is left alone"
|
||||
@@ -10,6 +10,10 @@ grep -Fq 'KERNEL_CMDLINE[default]+=" initramfs_async=0"' "$packaged_defaults" ||
|
||||
fail "the packaged Limine defaults still unpack the initramfs synchronously"
|
||||
pass "packaged Limine defaults keep Plymouth alive at the LUKS prompt"
|
||||
|
||||
grep -Fxq 'KERNEL_CMDLINE[default]+=" systemd.tty.term.console=dumb"' "$packaged_defaults" ||
|
||||
fail "the packaged Limine defaults let PID 1 wait for the console to answer a size query"
|
||||
pass "packaged Limine defaults keep PID 1 from waiting on the console"
|
||||
|
||||
grep -Fxq 'BOOT_ORDER="linux-t2, linux-omarchy, linux-omarchy-*, *, *fallback, Snapshots"' "$packaged_defaults" ||
|
||||
fail "packaged Limine defaults protect T2 Macs and prefer the exact Omarchy kernel elsewhere"
|
||||
pass "packaged Limine defaults protect T2 Macs and prefer the exact Omarchy kernel elsewhere"
|
||||
Reference in new issue
Block a user