From 190ff0d0a8d1fc367ec04296f24cd1cab5b7543b Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 1 Feb 2024 09:13:10 +0100 Subject: [PATCH] vconsole-setup: don't fail if the only found vc is already used by plymouth During the boot process, systemd-vconsole-setup can be started when the only allocated VC is already taken by plymouth. This case is expected when a boot splash is displayed hence systemd-vconsole-setup.service should not fail if it happens. However rather than doing nothing, the sysfs utf8 flag is set before exiting early. --- src/vconsole/vconsole-setup.c | 48 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 554d00e5b7..bc32b2267c 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -521,14 +521,21 @@ static int find_source_vc(char **ret_path, unsigned *ret_idx) { assert(ret_path); assert(ret_idx); + /* This function returns an fd when it finds a candidate. When it fails, it returns the first error + * that occured when the VC was being opened or -EBUSY when it finds some VCs but all are busy + * otherwise -ENOENT when there is no allocated VC. */ + for (unsigned i = 1; i <= 63; i++) { _cleanup_close_ int fd = -EBADF; _cleanup_free_ char *path = NULL; + /* We save the first error but we give less importance for the case where we previously fail + * due to the VCs being not allocated. Similarly errors on opening a device has a higher + * priority than errors due to devices either not allocated or busy. */ + r = verify_vc_allocation(i); if (r < 0) { - log_debug_errno(r, "VC %u existence check failed, skipping: %m", i); - RET_GATHER(err, r); + RET_GATHER(err, log_debug_errno(r, "VC %u existence check failed, skipping: %m", i)); continue; } @@ -537,29 +544,37 @@ static int find_source_vc(char **ret_path, unsigned *ret_idx) { fd = open_terminal(path, O_RDWR|O_CLOEXEC|O_NOCTTY); if (fd < 0) { - RET_GATHER(err, log_debug_errno(fd, "Failed to open terminal %s, ignoring: %m", path)); + log_debug_errno(fd, "Failed to open terminal %s, ignoring: %m", path); + if (IN_SET(err, 0, -EBUSY, -ENOENT)) + err = fd; continue; } r = verify_vc_kbmode(fd); if (r < 0) { - RET_GATHER(err, log_debug_errno(r, "Failed to check VC %s keyboard mode: %m", path)); + log_debug_errno(r, "Failed to check VC %s keyboard mode: %m", path); + if (IN_SET(err, 0, -ENOENT)) + err = r; continue; } r = verify_vc_display_mode(fd); if (r < 0) { - RET_GATHER(err, log_debug_errno(r, "Failed to check VC %s display mode: %m", path)); + log_debug_errno(r, "Failed to check VC %s display mode: %m", path); + if (IN_SET(err, 0, -ENOENT)) + err = r; continue; } + log_debug("Selecting %s as source console", path); + /* all checks passed, return this one as a source console */ *ret_idx = i; *ret_path = TAKE_PTR(path); return TAKE_FD(fd); } - return log_error_errno(err, "No usable source console found: %m"); + return err; } static int verify_source_vc(char **ret_path, const char *src_vc) { @@ -610,14 +625,26 @@ static int run(int argc, char **argv) { umask(0022); - if (argv[1]) + if (argv[1]) { fd = verify_source_vc(&vc, argv[1]); - else + if (fd < 0) + return fd; + } else { fd = find_source_vc(&vc, &idx); - if (fd < 0) - return fd; + if (fd < 0 && fd != -EBUSY) + return log_error_errno(fd, "No usable source console found: %m"); + } utf8 = is_locale_utf8(); + (void) toggle_utf8_sysfs(utf8); + + if (fd < 0) { + /* We found only busy VCs, which might happen during the boot process when the boot splash is + * displayed on the only allocated VC. In this case we don't interfer and avoid initializing + * the VC partially as some operations are likely to fail. */ + log_notice("All allocated VCs are currently busy, skipping initialization of font and keyboard settings."); + return EXIT_SUCCESS; + } context_load_config(&c); @@ -629,7 +656,6 @@ static int run(int argc, char **argv) { else if (lock_fd < 0) return log_error_errno(lock_fd, "Failed to lock /dev/console: %m"); - (void) toggle_utf8_sysfs(utf8); (void) toggle_utf8_vc(vc, fd, utf8); r = font_load_and_wait(vc, &c); -- 2.25.1