Skip to content

vconsole-setup: always run setfont(8) despite empty /etc/vconsole.conf#15479

Closed
mikhailnov wants to merge 1 commit intosystemd:masterfrom
mikhailnov:vconsole-setfont-always
Closed

vconsole-setup: always run setfont(8) despite empty /etc/vconsole.conf#15479
mikhailnov wants to merge 1 commit intosystemd:masterfrom
mikhailnov:vconsole-setfont-always

Conversation

@mikhailnov
Copy link
Copy Markdown
Contributor

If /etc/vconsole.conf and kernel cmdline options are empty, systemd-vconsole-setup
will do nothing and the user will get a TTY with an incorrect font. E.g. Russian
users may get a TTY with a font that does not support cyrillic characters.

It may happen because TTY is set up at initrd stage, but dracut for some reasons
does not include /etc/vconsole.conf into generic initrds:
dracutdevs/dracut#796

It is reported by ROSA users and QA that, without Plymouth, they get normal fonts
without /etc/vconsole.conf in initrd. I don't know how it may happen.

If we get a TTY with an incorrect font, running "setfont" will force setting a
default font. kbd package in many distros controls the default font:

rosa-2016 ~ # rpm -ql kbd | grep default
/usr/lib/kbd/consolefonts/default.psfu.gz
/usr/lib/kbd/consolefonts/default8x16.psfu.gz
/usr/lib/kbd/consolefonts/default8x9.psfu.gz
rosa-2016 ~ # file /usr/lib/kbd/consolefonts/default.psfu.gz
/usr/lib/kbd/consolefonts/default.psfu.gz: symbolic link to LatGrkCyr-8x16.psfu.gz

In some distors, e.g. Ubuntu, there is no default.psfu symlink and setfont reports that
it can't find the default font, but it is a distro-specific problem. This patch makes
systemd-vconsole-setup rely on setfont(8) to find the default font if none is specified
in /etc/vconsole.conf or kernel command line options.

If /etc/vconsole.conf and kernel cmdline options are empty, systemd-vconsole-setup
will do nothing and the user will get a TTY with an incorrect font. E.g. Russian
users may get a TTY with a font that does not support cyrillic characters.

It may happen because TTY is set up at initrd stage, but dracut for some reasons
does not include /etc/vconsole.conf into generic initrds:
dracutdevs/dracut#796

It is reported by ROSA users and QA that, without Plymouth, they get normal fonts
without /etc/vconsole.conf in initrd. I don't know how it may happen.

If we get a TTY with an incorrect font, running "setfont" will force setting a
default font. kbd package in many distros controls the default font:

rosa-2016 ~ # rpm -ql kbd | grep default
/usr/lib/kbd/consolefonts/default.psfu.gz
/usr/lib/kbd/consolefonts/default8x16.psfu.gz
/usr/lib/kbd/consolefonts/default8x9.psfu.gz
rosa-2016 ~ # file /usr/lib/kbd/consolefonts/default.psfu.gz
/usr/lib/kbd/consolefonts/default.psfu.gz: symbolic link to LatGrkCyr-8x16.psfu.gz

In some distors, e.g. Ubuntu, there is no default.psfu symlink and setfont reports that
it can't find the default font, but it is a distro-specific problem. This patch makes
systemd-vconsole-setup rely on setfont(8) to find the default font if none is specified
in /etc/vconsole.conf or kernel command line options.

Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
mikhailnov added a commit to mikhailnov/dracut that referenced this pull request Apr 19, 2020
/etc/vconsole.conf must be installed always, even in generic initrds, not only host-only ones.
systemd-vconsole-setup is run at initrd stage and expects either /etc/vconsole.conf or kernel cmdline options to exist.

I have also proposed a change in systemd-vconsole-setup that makes it behave better if /etc/vconsole.conf does not exist:
systemd/systemd#15479
But it is just a fallback. If /etc/vconsole.conf does not exist in initrd and if that patch is applied on systemd,
then the default consoel font is set despite the one being set in /etc/vconsole.conf and this setting is inherited
when new TTYs are opened. This leads to full ignorance of settings in /etc/vconsole.conf.
It is incorrect, and that is why this file must be copied to initrds always, but not only on host-only initrds.

Fixes: dracutdevs#796

Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
mikhailnov added a commit to mikhailnov/dracut that referenced this pull request Apr 19, 2020
/etc/vconsole.conf must be installed always, even in generic initrds, not only host-only ones.
systemd-vconsole-setup is run at initrd stage and expects either /etc/vconsole.conf or kernel cmdline options to exist.

I have also proposed a change in systemd-vconsole-setup that makes it behave better if /etc/vconsole.conf does not exist:
systemd/systemd#15479
But it is just a fallback. If /etc/vconsole.conf does not exist in initrd and if that patch is applied on systemd,
then the default consoel font is set despite the one being set in /etc/vconsole.conf and this setting is inherited
when new TTYs are opened. This leads to full ignorance of settings in /etc/vconsole.conf.
It is incorrect, and that is why this file must be copied to initrds always, but not only on host-only initrds.

Fixes: dracutdevs#796

Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
haraldh pushed a commit to dracutdevs/dracut that referenced this pull request Apr 20, 2020
/etc/vconsole.conf must be installed always, even in generic initrds, not only host-only ones.
systemd-vconsole-setup is run at initrd stage and expects either /etc/vconsole.conf or kernel cmdline options to exist.

I have also proposed a change in systemd-vconsole-setup that makes it behave better if /etc/vconsole.conf does not exist:
systemd/systemd#15479
But it is just a fallback. If /etc/vconsole.conf does not exist in initrd and if that patch is applied on systemd,
then the default consoel font is set despite the one being set in /etc/vconsole.conf and this setting is inherited
when new TTYs are opened. This leads to full ignorance of settings in /etc/vconsole.conf.
It is incorrect, and that is why this file must be copied to initrds always, but not only on host-only initrds.

Fixes: #796

Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
@keszybz
Copy link
Copy Markdown
Member

keszybz commented Apr 20, 2020

Looks reasonable. Opinions?

@poettering
Copy link
Copy Markdown
Member

hmm, the default path doesn't exist on fedora at least afaics. are you sure this isn't just something your own distro does?

To me this kinda feels as if we should start supporting /usr/lib/vconsole.conf which then ships with a line appropriate for the local distro, no?

@mikhailnov
Copy link
Copy Markdown
Contributor Author

Right, it is a symlink: https://abf.io/import/kbd/blob/rosa2019.1/kbd.spec#lc-122
However, this follows what setfont(8) tells:

 The default font is a file default (or default8xN if the -N option was given for some number N) perhaps with suitable extension (like .psf).

So, a user or a distro packager may make such a symlink. I thought that most ditros have it. But I still do not see better options than executing setfont despite FONT being not set. A try to provide the user with a usable TTY seems to be better than no try at all.

To me this kinda feels as if we should start supporting /usr/lib/vconsole.conf which then ships with a line appropriate for the local distro, no?

it sounds like a bicycle, because the safe is already implemented in setfont...

@mikhailnov
Copy link
Copy Markdown
Contributor Author

(I doubt that it is a good idea to ship a hardcoded symlink in the package, but it can be controlled via a special utility or manually)

@keszybz
Copy link
Copy Markdown
Member

keszybz commented Apr 21, 2020

@mikhailnov can you find out what the setfont code actually does?

@poettering
Copy link
Copy Markdown
Member

(also note: if distros like fedora have no such symlink then this means this PR will break on fedora, as the command will simply fail then, no?)

@mikhailnov
Copy link
Copy Markdown
Contributor Author

mikhailnov commented Apr 21, 2020

@mikhailnov can you find out what the setfont code actually does?

It does exactly what is documented in the manual: tries to fallback to a font named "default" if no font has been specified. https://github.com/legionus/kbd/blob/master/src/setfont.c#L557

(also note: if distros like fedora have no such symlink then this means this PR will break on fedora, as the command will simply fail then, no?)

Maybe. It depends on how systemd-vconsole-setup treats failures of setfont. Now it fails if setfont failed. Agree, it is not good. But the current situation is also not good... systemd-vconsole-setup does not fail, but actually it fails to ship a desired result to the user and does not report a problem.

My patch has been applied in dracut, it is actually enough to achieve a desired result in typical configuration without patching systemd-vconsole-setup. I have been told that the same problem exists on Manjaro Linux, which uses another generator of initrd - mkinitcpio. The reason why I made this patch was because I wanted a more reliable behaviour than assuming that a needed config will be correct and will get inside initrd.

@legionus , you maintain both setfont and make-initrd, maybe you can somehow comment on how we should deal with this behaviour of setfont, which is called by systemd-vconsole-setup? Maybe a default font can be forced to exist on all distros?
I have looked at how it is implemented in ALT Linux where make-initrd is used, and found out that systemd-vconsole-setup is patched to additionally read just another config from /etc/sysconfig/. I know that make-initrd includes sysvinit inside the initrd, which then launches systemd, I don't know at which stage vconsole is initialized there.

Also, I still have not found an answer, why people without plymouth got a working font in the TTY despite /etc/vconsole.conf not existing in the initrd but existing in the system. Maybe the whole process of working with TTYs is broken..?

@legionus
Copy link
Copy Markdown

@legionus , you maintain both setfont and make-initrd, maybe you can somehow comment on how we should deal with this behaviour of setfont, which is called by systemd-vconsole-setup?

I think the current systemd-vconsole-setup behavior is correct. No need to call setfont if no font is specified. @mikhailnov, You are trying to replace the configuration with a symlink to the desired font. Yes, someone may use default font when they execute setfont, but this is not about setfont but about systemd-vconsole-setup.

Maybe a default font can be forced to exist on all distros?

Its existence has been required for many years. If there is no default font, an error is thrown.
I don’t really understand how you want to force everyone to make this symlink.

I have looked at how it is implemented in ALT Linux where make-initrd is used, and found out that systemd-vconsole-setup is patched to additionally read just another config from /etc/sysconfig/.

Yes. This is done due to backward compatibility.

I know that make-initrd includes sysvinit inside the initrd, which then launches systemd, I don't know at which stage vconsole is initialized there.

offtopic: There is no sysvinit in initrd, but something much more simpler.

We have a module that can load the console keymap and console font from the initrd. I know that sysvinit based installations (they are still supported) load keymap and font at startup without any problems. What happens on installations based on systemd I can’t say because I don’t use it.

Also, I still have not found an answer, why people without plymouth got a working font in the TTY despite /etc/vconsole.conf not existing in the initrd but existing in the system. Maybe the whole process of working with TTYs is broken..?

If something that worked for many years doesn’t work for you, then something is definitely broken :)

@mikhailnov
Copy link
Copy Markdown
Contributor Author

mikhailnov commented Apr 24, 2020 via email

@mikhailnov
Copy link
Copy Markdown
Contributor Author

Fedora had discussions about shipping a prebuilt initrd, all this will be a problem in case of a universal prebuilt initrd.

@gdamjan
Copy link
Copy Markdown
Contributor

gdamjan commented May 14, 2020

typically when I don't have vconsole.conf, or it's empty, I don't want setfont running at all, and want the kernel font untouched.

@keszybz
Copy link
Copy Markdown
Member

keszybz commented May 15, 2020

The code to locate the default font is here:
https://github.com/legionus/kbd/blob/bc603778b15c6703c9e432843d4d5c5f991373ca/src/libkfont/setfont.c#L394-L419. E.g. on Fedora this will find default8x16.psfu.gz.

Its existence has been required for many years. If there is no default font, an error is thrown.

So I think the question whether the default font is defined is not very important. It is or should be always defined.

The question then is whether we should call setfont when no settings whatsoever are defined. Proposed behaviour would make things more resilient for non-latin1 users where the distro defines a suitable default font. OTOH current behaviour might be used by people who do not want systemd-vconsole to run at all. In particular, this might be an optimization useful in VMs where the console is never used. I suspect that the latter are much more common.

(And there's always the argument that behaviour should not be changed unless there's a reason. So the new thing should be better, not just as good, to make a change....)

@mikhailnov
Copy link
Copy Markdown
Contributor Author

this might be an optimization useful in VMs where the console is never used

A TTY can be used for rescue purposes, and there a font, that displays all symbols correctly, will be useful

@keszybz
Copy link
Copy Markdown
Member

keszybz commented May 15, 2020

Yeah, my stmt was ambiguous: I didn't mean that ttys are never used in vms, but only that for some vms, they are not used.

@poettering
Copy link
Copy Markdown
Member

i am pretty sure we shouldn't try to add too many levels of fallback here. either have a config or don't. in the latter you'll get the kernel console's native built-in font. it's not great for non-latin world, but the console generally is awful for everything that isn't western-style alphabets, anyway. I mean, we are just talking about the level of brokeness of the console, not about the question whether it is broken at all or not at all. Because it is just awful for everything non-latin, non-cyrillic in general, and nothing is really going to change that (i mean, a 512 character subset of unicode, wtf?).

If you are technically savvy enough to use the console, and to fiddle around with console fonts and stuff, I think it's not too terrible if you end up with the kernel's built-in font if you fuck things up. If you want working, pretty, internationalized fonts, you'd use a graphical environment anyway. The console is for nerds really..

Really, I think having this many levels of config and fallbacks at different place is just unnecessary complexity. I'd hence really just close this PR. Sorry.

@mikhailnov
Copy link
Copy Markdown
Contributor Author

mikhailnov commented May 15, 2020

Well, when I opened this PR, I thought that default font exists in all distros, as it does not, I cannot diagree with all arguements written here. But what I still do not understand is why setting the console font depends from /etc/vconsole.conf being inside initrd. I mean, if it does not exist in initrd but does exist in the system, the font is still not set, at least when plymouth is on. When plymouth is off, the font is set. Can anyone explain why?

@gdamjan
Copy link
Copy Markdown
Contributor

gdamjan commented May 16, 2020

But what I still do not understand is why setting the console font depends from /etc/vconsole.conf being inside initrd.

that's not the behaviour on archlinux

@mikhailnov
Copy link
Copy Markdown
Contributor Author

mikhailnov commented May 16, 2020 via email

@poettering
Copy link
Copy Markdown
Member

we wont't rerun systemd-vconsole after the host transition if it was run before already (it runs with RemainsAfterExit=1). This means distros have to chose: either pack the service and the configuration file and the needed fronts into the initrd. Or neither of those. If they just ship the service, but not the config or not the font then we'll just use defaults, and then never try again.

Yes, this means vconsole config changes require an initrd rebuild. Which is the same as for most other early-boot config settings...

I figure many distros actually do pack up the whole of vconsole into the initrd, since they want keymaps to work for full disk encryption, and that's done by vconsole too.

I figure you probably need to report this to your distro/initrd buildr instead. And we probably can close this here. Does this make sense?

@keszybz
Copy link
Copy Markdown
Member

keszybz commented May 19, 2020

we wont't rerun systemd-vconsole after the host transition if it was run before already (it runs with RemainsAfterExit=1)

Ha, so this sounds like this is where the behaviour is wrong. We should just unconditionally run systemd-vconsole again in the real root, and it should do its thing. Relying on the configuration to be always up to date in the initramfs is very painful for users.

We also have a TODO entry or issue (or maybe it was just a random comment somewhere), to let vconsole remember which ttys it has already initialized, so it is possible to rerun it when new consoles pop up. So I think we could somehow combine those two things, and run the sd-vc in the initramfs, and let it drop a bunch of files in /run to mark any consoles that have been initialized (or xattrs in /dev or whatever), and use this when running in the real root to only touch those vcs for which we have differing configuration.

@poettering
Copy link
Copy Markdown
Member

we wont't rerun systemd-vconsole after the host transition if it was run before already (it runs with RemainsAfterExit=1)

Ha, so this sounds like this is where the behaviour is wrong. We should just unconditionally run systemd-vconsole again in the real root, and it should do its thing. Relying on the configuration to be always up to date in the initramfs is very painful for users.

Well, we have no nice way to do that, i.e. we serialize/deserialize unit state from initrd into the host, and thus assume the service worked fine in the initrd, and won't start it again (and I'd argue that's actually correct, after all we did run it correctly).

You could only sensibly do it if you introduce two distinct unit files for it: "systemd-vconsole-initrd.service" vs. the existing "systemd-vconsole.service", and the host would carry both, but the initrd only the former.

We also have a TODO entry or issue (or maybe it was just a random comment somewhere), to let vconsole remember which ttys it has already initialized, so it is possible to rerun it when new consoles pop up. So I think we could somehow combine those two things, and run the sd-vc in the initramfs, and let it drop a bunch of files in /run to mark any consoles that have been initialized (or xattrs in /dev or whatever), and use this when running in the real root to only touch those vcs for which we have differing configuration.

Quite frankly: this sounds like polishing a turd: the VC subsystem is unmaintained madness, I wouldn't add even more infrastructure to userspace just because noone wants to fix it properly in kernel-space. Let's keep this minimal even when this means we won't catch every single corner case. i.e. this all sounds like a documentation excercise to me: document what we support and what we don't, but don't keep figuring out every single time we might to reload again...

I figure out mean #11377?

@keszybz
Copy link
Copy Markdown
Member

keszybz commented May 19, 2020

I figure out mean #11377?

Yeah.

@mikhailnov
Copy link
Copy Markdown
Contributor Author

I figure you probably need to report this to your distro/initrd buildr instead. And we probably can close this here. Does this make sense?

As I am that distro builder, I want to understand how to deal with that correctly. Rerunning vconsole-setup after initrd stage seems to be a good solution but I'm not an expert. I don't see reasons why rerunning it would break things, but it will make life easier.

since they want keymaps to work for full disk encryption

What for? To enter passwords with non-ASCII symbols?

Quite frankly: this sounds like polishing a turd: the VC subsystem is unmaintained madness, I wouldn't add even more infrastructure to userspace just because noone wants to fix it properly in kernel-space.

But rerunning console setup is not a so difficult thing, is it? Currently there is a problem with logics: system-vconsole-setup relies on initrd where it seems to be not really needed. But I understand that rerunning makes things even more complicated. Ideally the font would be set when the TTY is opened, despite the state when vconsole-setup was started, I think.

@mikhailnov
Copy link
Copy Markdown
Contributor Author

As I am that distro builder, I want to understand how to deal with that correctly.

Currently default dracut behaviour is used.

@poettering
Copy link
Copy Markdown
Member

What for? To enter passwords with non-ASCII symbols?

it's not about ASCII vs. non-ASCII. Its already about "y" and "z". In us and de keyboards they are swapped even though the other letters generally match.

@poettering
Copy link
Copy Markdown
Member

i figure those who have an initrd want to run it in the initrd, and those who don't don't. hence we should make it possible to run it in either, but genreally only start it once

@mikhailnov
Copy link
Copy Markdown
Contributor Author

What for? To enter passwords with non-ASCII symbols?

it's not about ASCII vs. non-ASCII. Its already about "y" and "z". In us and de keyboards they are swapped even though the other letters generally match.

Does this mean that, if the user accidently did not manage to get a correct /etc/vconsole.conf into initrd, he may get an incorrectly working keyboard in TTY?

I actually don't catch your point why vconsole-setup should not be restarted; which problems will appear if it is restarted?

@mikhailnov
Copy link
Copy Markdown
Contributor Author

Fedora had discussions about shipping a prebuilt initrd, all this will be a problem in case of a universal prebuilt initrd.

Has this ever been discussed? I would also like to ship prebuilt initrds in RPM packages, and there we can not make a universal /etc/vconsole.conf, so vconsole-setup will have to be restarted...

@legionus
Copy link
Copy Markdown

I actually don't catch your point why vconsole-setup should not be restarted; which problems will appear if it is restarted?

Moreover, the fact that vconsole-setup should not restart apparently comes from the fact that the console configuration is unchanged, but this is not so. Keymap and console font may differ on different consoles. This is especially noticeable on a multi-user system.

It is very strange to hear that systemd does this regression in console configuration.

@poettering
Copy link
Copy Markdown
Member

Does this mean that, if the user accidently did not manage to get a correct /etc/vconsole.conf into initrd, he may get an incorrectly working keyboard in TTY?

Yes. The configuration for the kbd must come from somewhere, i.e. either /etc/vconsole.conf must be kept up to date in the initrd, or the kernel cmdline option vconsole.keymap= must be set.

I actually don't catch your point why vconsole-setup should not be restarted; which problems will appear if it is restarted?

you can restart it of course, it's entirely up to you to hack this the way you like. but I don#t think this should be the codeflow we provide by default: we should set the kbd settings once, and if FDE shall be supported then this means in the initrd. And FDE is not an issue, then it can be after the host transition. But pick one. There's no point in doing this twice.

@poettering
Copy link
Copy Markdown
Member

Has this ever been discussed? I would also like to ship prebuilt initrds in RPM packages, and there we can not make a universal /etc/vconsole.conf, so vconsole-setup will have to be restarted...

There have been meetings, but noone is championing to actually do the work. So don't hold your breath...

Three options where discussed regarding passing configuration such as kbd map to the initrd:

  1. pass them through the kernel cmdline, i.e update boot loader entries whenever kbd map changes
  2. introduce a new file to store the the boot loader fs that contains this info, and leave it to the boot loader to load it, and mangle it and append it to the kernel cmdline. benefit: boot loader can honour the settings in there too, after all a boot loader might want keymaps too, most boot loaders are interactive after all
  3. have two initrds: the pre-built one from the OS vendor. Plus a dynamically generated one just containing /etc/vconsole.conf and nothing else. Then pass both to the kernel when booting. Kernels support that just fine and will first unpack the first and then the second.

Another new option might be to make use of this new kernel feature: https://www.kernel.org/doc/html/latest/admin-guide/bootconfig.html — maybe just make the boot loader load a file in this format off the boot partition and pass it to the kernel along with everything else.

@poettering
Copy link
Copy Markdown
Member

I think we can close this here now. I am not convinced this PR should go in the way it is. If there's work to be done here, it should probably be in a new PR

@poettering poettering closed this Aug 18, 2020
@mikhailnov
Copy link
Copy Markdown
Contributor Author

mikhailnov commented Aug 19, 2020 via email

mikhailnov added a commit to mikhailnov/livecd-tools that referenced this pull request Oct 10, 2020
1. eurlatgr font is not universal and does not cupport cyrillic characters
livecd-tools#159
2. We patch systemd to run setfont despite empty /etc/vconsole.conf
systemd/systemd#15479
This patch can be dropped in the future, however.
mikhailnov added a commit to mikhailnov/livecd-tools that referenced this pull request May 31, 2021
1. eurlatgr font is not universal and does not cupport cyrillic characters
livecd-tools#159
2. We patch systemd to run setfont despite empty /etc/vconsole.conf
systemd/systemd#15479
This patch can be dropped in the future, however.
mikhailnov added a commit to mikhailnov/livecd-tools that referenced this pull request Jun 27, 2021
1. eurlatgr font is not universal and does not cupport cyrillic characters
livecd-tools#159
2. We patch systemd to run setfont despite empty /etc/vconsole.conf
systemd/systemd#15479
This patch can be dropped in the future, however.
mikhailnov added a commit to mikhailnov/livecd-tools that referenced this pull request Sep 13, 2021
1. eurlatgr font is not universal and does not cupport cyrillic characters
livecd-tools#159
2. We patch systemd to run setfont despite empty /etc/vconsole.conf
systemd/systemd#15479
This patch can be dropped in the future, however.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

5 participants