[PATCH procd] utils: fix get_active_console when kernel returns multiple values

Mathew McBride matt at traverse.com.au
Mon Jan 24 19:12:08 PST 2022


/sys/class/tty/console/active may return multiple values on
kernels where framebuffer support is enabled but the system
is supposed to be using a serial console.
e.g
$ cat /sys/class/tty/console/active
tty0 ttyS0

On such systems, tty0 is a dummy console:
[    0.008273] Console: colour dummy device 80x25
[    0.012742] printk: console [tty0] enabled

The serial console doesn't appear until much later:
[    0.092468] 21c0500.serial: ttyS0 at MMIO 0x21c0500
[    1.713893] printk: console [ttyS0] enabled

So far this only appears to happen on systems using
device tree.

In these circumstances, use the last console device
shown in the sysfs active file.

Fixes: 2cfc26f ("inittab: detect active console from kernel if no console= specified")
Signed-off-by: Mathew McBride <matt at traverse.com.au>
---
 utils/utils.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/utils/utils.c b/utils/utils.c
index f0c4a90..43b24c6 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -138,6 +138,10 @@ blobmsg_list_equal(struct blobmsg_list *l1, struct blobmsg_list *l2)
 char *get_active_console(char *out, int len)
 {
 	char line[CMDLINE_SIZE + 1];
+	char *sptr, *token;
+	char *console = NULL;
+
+	memset(line, 0, sizeof(line));
 	int fd = open("/sys/class/tty/console/active", O_RDONLY);
 	ssize_t r;
 
@@ -152,15 +156,22 @@ char *get_active_console(char *out, int len)
 	if (r <= 0)
 		return NULL;
 
-	/* The active file is terminated by a newline which we need to strip */
-	char *newline = strtok(line, "\n");
-
-	if (newline != NULL) {
-		strncpy(out, newline, len);
-		return out;
+	/* There may be multiple 'active' consoles.
+	 * On kernels that support both graphical and
+	 * serial consoles, Linux may create a 'dummy'
+	 * framebuffer console on tty0 if no other console
+	 * device has been probed yet. Often a serial
+	 * driver (e.g ttyS0) might only be probed later
+	 * in the boot process.
+	 */
+	for (token = strtok_r(line, " \t\n", &sptr); token;
+	     token = strtok_r(NULL, " \t\n", &sptr)) {
+		strncpy(out, token, len);
+		console = out;
 	}
+	out[len-1] = '\0';
 
-	return NULL;
+	return console;
 }
 
 char* get_cmdline_val(const char* name, char* out, int len)
-- 
2.30.1




More information about the openwrt-devel mailing list