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.
This commit is contained in:
Franck Bui 2024-02-01 09:13:10 +01:00 committed by Lennart Poettering
parent 78bbc7d5d4
commit 190ff0d0a8

View file

@ -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);