[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