Blob Blame History Raw
From d80b4dbf2c0d91ad54c2c0a0296096293ed59b39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 24 May 2017 23:25:44 -0400
Subject: [PATCH] vconsole-setup: skip setting fonts when setfont returns
 EX_OSERR
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On a machine without a VGA console, /dev/tty{0,1,…} exist, so
systemd-vconsole-setup is started, but all setfont operations fail.

setfont has a bunch of return codes for different failure modes. It uses
EX_OSERR when the communication with the kernel using ioctls fails. This isn't
too specific, but at least it's only used this general class of errors. Let's
swallow the error in this case to avoid systemd-vconsole-setup.service failing
on cloud vms.

On a machine from https://bugzilla.redhat.com/show_bug.cgi?id=1272686#c4:
$ build/systemd-vconsole-setup
setfont: putfont: 512,8x16:  failed: -1
putfont: PIO_FONT: Invalid argument
/usr/bin/setfont failed with error code 71.
Setting fonts failed with a "system error", ignoring.

$ SYSTEMD_LOG_LEVEL=debug build/systemd-vconsole-setup
Found container virtualization none.
Sysfs UTF-8 flag enabled
UTF-8 kbdmode enabled on /dev/tty0
Executing "/usr/bin/setfont -C /dev/tty0 eurlatgr"...
setfont: putfont: 512,8x16:  failed: -1
putfont: PIO_FONT: Invalid argument
/usr/bin/setfont failed with error code 71.
Executing "/usr/bin/loadkeys -q -C /dev/tty0 -u us"...
/usr/bin/loadkeys succeeded.
Setting fonts failed with a "system error", ignoring.

$ lspci | grep -i vga

$ ls /dev/tty?
/dev/tty0  /dev/tty2  /dev/tty4  /dev/tty6  /dev/tty8
/dev/tty1  /dev/tty3  /dev/tty5  /dev/tty7  /dev/tty9

If we have a better test for /dev/tty? being connected to something that has a
font, we could avoid running setfont at all… ATM, I'm not aware of a simple
test like that.

(cherry picked from commit 93c9a9d235e2304500c490b4868534385f925c76)
---
 src/vconsole/vconsole-setup.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index 2401077be5..dc63bb530c 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/ioctl.h>
+#include <sysexits.h>
 #include <termios.h>
 #include <unistd.h>
 
@@ -336,8 +337,8 @@ int main(int argc, char **argv) {
                 *vc_keymap = NULL, *vc_keymap_toggle = NULL,
                 *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
         _cleanup_close_ int fd = -1;
-        bool utf8, font_copy = false, font_ok, keyboard_ok;
-        int r = EXIT_FAILURE;
+        bool utf8, font_copy = false, keyboard_ok;
+        int r;
 
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
@@ -382,7 +383,6 @@ int main(int argc, char **argv) {
                            "FONT_MAP", &vc_font_map,
                            "FONT_UNIMAP", &vc_font_unimap,
                            NULL);
-
         if (r < 0 && r != -ENOENT)
                 log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m");
 
@@ -399,22 +399,27 @@ int main(int argc, char **argv) {
                                    "vconsole.font.map", &vc_font_map,
                                    "vconsole.font.unimap", &vc_font_unimap,
                                    NULL);
-
                 if (r < 0 && r != -ENOENT)
                         log_warning_errno(r, "Failed to read /proc/cmdline: %m");
         }
 
         toggle_utf8_sysfs(utf8);
         toggle_utf8(vc, fd, utf8);
-        font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0;
+
+        r = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap);
         keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0;
 
         if (font_copy) {
-                if (font_ok)
+                if (r == 0)
                         setup_remaining_vcs(fd, utf8);
+                else if (r == EX_OSERR)
+                        /* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails.
+                         * This might mean various things, but in particular lack of a graphical
+                         * console. Let's be generous and not treat this as an error. */
+                        log_notice("Setting fonts failed with a \"system error\", ignoring.");
                 else
                         log_warning("Setting source virtual console failed, ignoring remaining ones");
         }
 
-        return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
+        return IN_SET(r, 0, EX_OSERR) && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
 }