pid1,vconsole-setup: take a lock for the console device

When systemd-firstboot (or any other unit which uses the tty) is started,
systemd will reset the terminal. If systemd-vconsole-setup happens to be
running at that time, it'll error out when it tries to use the vconsole fd and
gets an EIO from ioctl.

e019ea738d was the first fix. It added an
implicit ordering between units using the tty and systemd-vconsole-setup.
(The commit title is wrong. The approach was generalized, but the commit title
wasn't updated.)
Then cea32691c3 was added to restart
systemd-vconsole-setup.service from systemd-firstboot.service. This was OK,
with the ordering in place, systemd-vconsole-setup.service would wait until
systemd-firstboot.service exited. But this wasn't enough, because we want the
key mappings to be loaded immediately after systemd-firstboot writes the
config. 8eb668b9ab implemented that, but actually
reintroduced the original issue. I had to drop the ordering between the two
units because otherwise we'd deadlock, waiting from firstboot for
vconsole-setup which wouldn't start while firstboot was running.
Restarting vconsole-setup.service from systemd-firstboot.service works just
fine, but when vconsole-setup.service is started earlier, it may be interrupted
by systemd-firstboot.service.

To resolve the issue, let's take a lock around the tty device. The reset is
performed after fork, so the (short) delay should not matter too much.

In xopenat_lock() the assert on <path> is dropped so that we can call
xopenat(fd, NULL) to get a copy of the original fd.

Fixes #26908.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2023-07-13 10:47:12 +02:00
parent 84214541fa
commit a0043bfa51
3 changed files with 33 additions and 16 deletions
-1
View File
@@ -1172,7 +1172,6 @@ int xopenat_lock(
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
assert(IN_SET(operation & ~LOCK_NB, LOCK_EX, LOCK_SH));
/* POSIX/UNPOSIX locks don't work on directories (errno is set to -EBADF so let's return early with