[PATCH] failsafe: run on all consoles listed in /proc/cmdline

Mark Mentovai mark at moxienet.com
Sun Jun 5 09:32:44 PDT 2022

On x86, when both CONFIG_GRUB_CONSOLE and CONFIG_GRUB_SERIAL are set (as
they are by default), the kernel command line will have two console=
entries, such as

    console=tty0 console=ttyS0,115200n8

Failsafe was only running a shell on the first defined console, the VGA
console. This is a problem for devices like apu2, where there is only a
serial console and it appears on ttyS0.

In contrast, the bootloader (GRUB) operates on both the serial console
and the VGA console by virtue of "terminal_{input,output} console
serial". The presence of two console= kernel command line parameters
causes kernel messages to be delivered to both. Under normal operation
(not failsafe), procd runs login in accordance with inittab, which on
x86 specifies ttyS0, hvc0, and tty1, allowing login through any of
serial, hypervisor, or VGA console. Thus, serial access was consistently
available on x86 devices with serial consoles under normal operation,
except for shell access in failsafe mode (without editing the kernel
command line).

By running shells on all consoles listed in /proc/cmdline, failsafe mode
will work correctly on devices with a serial console (like apu2), and
the same image without any need for reconfiguration can be shared by
devices with the more traditional (for x86) VGA console.

Signed-off-by: Mark Mentovai <mark at moxienet.com>
 .../files/lib/preinit/99_10_failsafe_login        | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/package/base-files/files/lib/preinit/99_10_failsafe_login b/package/base-files/files/lib/preinit/99_10_failsafe_login
index 1410c5f0db5f..6f4af3f28b53 100644
--- a/package/base-files/files/lib/preinit/99_10_failsafe_login
+++ b/package/base-files/files/lib/preinit/99_10_failsafe_login
@@ -2,13 +2,14 @@
 # Copyright (C) 2010 Vertical Communications
 failsafe_shell() {
-	local console="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | head -1 | sed -e 's/^console=//' -e 's/,.*//')"
-	[ -n "$console" ] || console=console
-	[ -c "/dev/$console" ] || return 0
-	while true; do
-		ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
-		sleep 1
-	done &
+	local consoles="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | sed -e 's/^console=//' -e 's/,.*//')"
+	[ -n "$consoles" ] || consoles=console
+	for console in $consoles; do
+		[ -c "/dev/$console" ] && while true; do
+			ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
+			sleep 1
+		done &
+	done
 boot_hook_add failsafe failsafe_shell

More information about the openwrt-devel mailing list