terminal-util: teach resolve_dev_console() to deal correctly with /dev/console being a symlink

/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.
This commit is contained in:
Lennart Poettering
2024-07-19 11:44:04 +02:00
parent 4a24cc859f
commit dffbe1d152
+20 -6
View 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