]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vconsole-setup: skip setfont(8) when the console driver lacks font support
authorFranck Bui <fbui@suse.com>
Wed, 8 Apr 2026 16:39:58 +0000 (18:39 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 9 Apr 2026 13:55:50 +0000 (14:55 +0100)
Don't run setfont(8) on consoles that don't support
fonts. systemd-vconsole-setup neither fails nor reports errors on such consoles
unlike setfont(8) which emits the following error [1]:

 systemd-vconsole-setup[169]: setfont: ERROR kdfontop.c:183 put_font_kdfontop: Unable to load such font with such kernel version

The check already existed in setup_remaining_vcs() but it was performed too
late.

[1] this was simply ignored by setfont(8) until
https://github.com/legionus/kbd/commit/1e15af4d8b272ca50e9ee1d0c584c5859102c848

src/vconsole/vconsole-setup.c

index e6da288e427eb7b323a211a6ec0dd9e3f951f328..73bf240cf513089aa468bfa9abe6f2e4316f4968 100644 (file)
@@ -215,6 +215,22 @@ static int verify_vc_display_mode(int fd) {
         return mode != KD_TEXT ? -EBUSY : 0;
 }
 
+static int verify_vc_support_font(int fd) {
+        struct console_font_op cfo = {
+                .op        = KD_FONT_OP_GET,
+                .width     = UINT_MAX,
+                .height    = UINT_MAX,
+                .charcount = UINT_MAX,
+        };
+
+        assert(fd >= 0);
+
+        if (ioctl(fd, KDFONTOP, &cfo) < 0)
+                return ERRNO_IS_NOT_SUPPORTED(errno) ? 0 : -errno;
+
+        return 1;
+}
+
 static int toggle_utf8_vc(const char *name, int fd, bool utf8) {
         int r;
         struct termios tc = {};
@@ -315,7 +331,7 @@ static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
         return 1; /* Report that we did something */
 }
 
-static int font_load_and_wait(const char *vc, Context *c) {
+static int font_load_and_wait(int fd, const char *vc, Context *c) {
         const char* args[9];
         unsigned i = 0;
         int r;
@@ -340,6 +356,16 @@ static int font_load_and_wait(const char *vc, Context *c) {
                 return 0; /* Report that we skipped this */
         }
 
+        /* May be called on the dummy console (e.g. during keymap setup with fbcon deferred takeover). Font
+         * changes are not supported here and will fail. */
+        r = verify_vc_support_font(fd);
+        if (r < 0)
+                return log_error_errno(r, "Failed to check '%s' has font support: %m", vc);
+        if (r == 0) {
+                log_notice("'%s' has no font support, skipping.", vc);
+                return 0; /* Report that we skipped this */
+        }
+
         args[i++] = KBD_SETFONT;
         args[i++] = "-C";
         args[i++] = vc;
@@ -371,9 +397,8 @@ static int font_load_and_wait(const char *vc, Context *c) {
                 _exit(EXIT_FAILURE);
         }
 
-        /* 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. */
+        /* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails. Let's be generous and not
+         * treat this as an error. */
         r = pidref_wait_for_terminate_and_check(KBD_SETFONT, &pidref, WAIT_LOG_ABNORMAL);
         if (r < 0)
                 return r; /* WAIT_LOG_ABNORMAL means we already have logged about these kinds of errors */
@@ -404,7 +429,7 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
         struct unimapdesc unimapd;
         _cleanup_free_ struct unipair* unipairs = NULL;
         _cleanup_free_ void *fontbuf = NULL;
-        int log_level = LOG_WARNING, r;
+        int r;
 
         assert(src_fd >= 0);
 
@@ -415,14 +440,7 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
         /* get metadata of the current font (width, height, count) */
         r = ioctl(src_fd, KDFONTOP, &cfo);
         if (r < 0) {
-                /* We might be called to operate on the dummy console (to setup keymap
-                 * mainly) when fbcon deferred takeover is used for example. In such case,
-                 * setting font is not supported and is expected to fail. */
-                if (errno == ENOSYS)
-                        log_level = LOG_DEBUG;
-
-                log_full_errno(log_level, errno,
-                               "KD_FONT_OP_GET failed while trying to get the font metadata: %m");
+                log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m");
         } else {
                 /* verify parameter sanity first */
                 if (cfo.width > 32 || cfo.height > 32 || cfo.charcount > 512)
@@ -458,7 +476,7 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
         }
 
         if (cfo.op != KD_FONT_OP_SET)
-                log_full(log_level, "Fonts will not be copied to remaining consoles");
+                log_warning("Fonts will not be copied to remaining consoles");
 
         for (unsigned i = 1; i <= 63; i++) {
                 char ttyname[sizeof("/dev/tty63")];
@@ -656,7 +674,7 @@ static int run(int argc, char **argv) {
 
         (void) toggle_utf8_vc(vc, fd, utf8);
 
-        int setfont_status = font_load_and_wait(vc, &c);
+        int setfont_status = font_load_and_wait(fd, vc, &c);
         int loadkeys_status = keyboard_load_and_wait(vc, &c, utf8);
 
         if (idx > 0) {