/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 <m...@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


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to