From a6c23b4d8ad84fff4a58855b76b56a261ff8aa5e Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Mon, 4 May 2026 13:20:13 +0200 Subject: [PATCH] Ensure to detect all special console case on S390x Signed-off-by: Werner Fink --- login-utils/sulogin-consoles.c | 46 ++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c index f09d90ece..4cce4f078 100644 --- a/login-utils/sulogin-consoles.c +++ b/login-utils/sulogin-consoles.c @@ -312,7 +312,7 @@ static #ifdef __GNUC__ __attribute__((__hot__)) #endif -int append_console(struct list_head *consoles, const char * const name) +int append_console(struct list_head *consoles, const char * const name, dev_t dev) { struct console *restrict tail; const struct console *last = NULL; @@ -343,7 +343,29 @@ int append_console(struct list_head *consoles, const char * const name) tail->reset_tty_context = NULL; tail->user_tty_context = NULL; #endif - +#if defined(__s390__) || defined(__s390x__) + /* + * Stat the device path to determine its major/minor numbers. + * This ensures we detect s390x terminal types regardless of whether + * the console was found via /proc, /sys, cmdline, or a direct stdin + * fallback (e.g. sulogin < /dev/ttyS0). + */ + if (!dev) { + struct stat st; + if (stat(name, &st) == 0 && S_ISCHR(st.st_mode)) + dev = st.st_rdev; + } + if (dev) { + unsigned int maj = major(dev); + unsigned int min = minor(dev); + if (maj == 4 && min == 64) + tail->flags |= CON_3215; + else if (maj == 4 && min >= 65) + tail->flags |= CON_SCLP; + else if (maj == 227 && min >= 1) + tail->flags |= CON_3270; + } +#endif return 0; } @@ -385,7 +407,7 @@ static int detect_consoles_from_proc(struct list_head *consoles) name = scandev(dir, comparedev); if (!name) continue; - rc = append_console(consoles, name); + rc = append_console(consoles, name, comparedev); free(name); if (rc < 0) goto done; @@ -394,14 +416,6 @@ static int detect_consoles_from_proc(struct list_head *consoles) last = list_last_entry(consoles, struct console, entry); if (!strchr(fbuf, 'C')) last->flags |= CON_CONSDEV; -#if defined(__s390__) || defined(__s390x__) - if (maj == 4 && min == 64) - last->flags |= CON_3215; - if (maj == 4 && min >= 65) - last->flags |= CON_SCLP; - else if (maj == 227 && min >= 1) - last->flags |= CON_3270; -#endif } } @@ -461,7 +475,7 @@ static int detect_consoles_from_sysfs(struct list_head *consoles) name = scandev(dir, comparedev); if (!name) continue; - rc = append_console(consoles, name); + rc = append_console(consoles, name, comparedev); free(name); if (rc < 0) goto done; @@ -549,7 +563,7 @@ static int detect_consoles_from_cmdline(struct list_head *consoles) name = scandev(dir, comparedev); if (!name) continue; - rc = append_console(consoles, name); + rc = append_console(consoles, name, comparedev); free(name); if (rc < 0) goto done; @@ -607,7 +621,7 @@ static int detect_consoles_from_tiocgdev(struct list_head *consoles, goto done; } } - rc = append_console(consoles, name); + rc = append_console(consoles, name, comparedev); free(name); if (rc < 0) goto done; @@ -721,7 +735,7 @@ int detect_consoles(const char *device, const int fallback, struct list_head *co closedir(dir); if (name) { - rc = append_console(consoles, name); + rc = append_console(consoles, name, comparedev); free(name); if (rc < 0) return rc; @@ -798,7 +812,7 @@ fallback: n = strdup(name); if (!n) return -ENOMEM; - rc = append_console(consoles, n); + rc = append_console(consoles, n, 0); free(n); if (rc < 0) return rc; -- 2.51.0