]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: teach resolve_dev_console() to deal correctly with /dev/console being...
authorLennart Poettering <lennart@poettering.net>
Wed, 17 Jul 2024 10:28:53 +0000 (12:28 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Jul 2024 09:44:04 +0000 (11:44 +0200)
/dev/console is sometimes a symlink in container managers. Let's handle
that correctly, and resolve the symlink, and not consider the data from
/sys/ in that case.

src/basic/terminal-util.c

index 6d3a0f8a5c7d79db3b521885e7f81a6ce3647fbf..93f356bde06ec11fa308275f517d5205ede0e3ab 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "alloc-util.h"
 #include "ansi-color.h"
+#include "chase.h"
 #include "constants.h"
 #include "devnum-util.h"
 #include "env-util.h"
@@ -698,24 +699,37 @@ int vtnr_from_tty(const char *tty) {
 }
 
 int resolve_dev_console(char **ret) {
-        _cleanup_free_ char *active = NULL;
-        char *tty;
         int r;
 
         assert(ret);
 
-        /* Resolve where /dev/console is pointing to, if /sys is actually ours (i.e. not read-only-mounted which is a
-         * sign for container setups) */
+        /* Resolve where /dev/console is pointing to. If /dev/console is a symlink (like in container
+         * managers), we'll just resolve the symlink. If it's a real device node, we'll use if
+         * /sys/class/tty/tty0/active, but only if /sys/ is actually ours (i.e. not read-only-mounted which
+         * is a sign for container setups). */
 
-        if (path_is_read_only_fs("/sys") > 0)
+        _cleanup_free_ char *chased = NULL;
+        r = chase("/dev/console", /* root= */ NULL, /* chase_flags= */ 0,  &chased, /* ret_fd= */ NULL);
+        if (r < 0)
+                return r;
+        if (!path_equal(chased, "/dev/console")) {
+                *ret = TAKE_PTR(chased);
+                return 0;
+        }
+
+        r = path_is_read_only_fs("/sys");
+        if (r < 0)
+                return r;
+        if (r > 0)
                 return -ENOMEDIUM;
 
+        _cleanup_free_ char *active = NULL;
         r = read_one_line_file("/sys/class/tty/console/active", &active);
         if (r < 0)
                 return r;
 
         /* If multiple log outputs are configured the last one is what /dev/console points to */
-        tty = strrchr(active, ' ');
+        const char *tty = strrchr(active, ' ');
         if (tty)
                 tty++;
         else