Merge pull request #27867 from keszybz/vconsole-reload-again

Restore ordering between vconsole-setup and firstboot services
This commit is contained in:
Luca Boccassi 2023-07-14 23:06:18 +01:00 committed by GitHub
commit 9027aff9d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 66 deletions

View file

@ -32,14 +32,17 @@
<refsect1>
<title>Description</title>
<para><filename>systemd-vconsole-setup</filename> sets up and configures either all virtual consoles, or — if the
optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system is booting up, it's
called by <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry> during
VT console subsystem initialization. Also,
<citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> invokes
it as needed when language or console changes are made. Internally, this program calls <citerefentry
project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry> and <citerefentry
project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
<para><filename>systemd-vconsole-setup</filename> sets up and configures either all virtual consoles, or
— if the optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system
is booting up, <filename>systemd-vconsole-setup.service</filename> is called by
<citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry> during
VT console subsystem initialization. Also,
<citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
invokes it as needed when language or console changes are made.
Internally, this program calls
<citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>
and
<citerefentry project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
<para>Execute <command>systemctl restart systemd-vconsole-setup.service</command> in order to apply any manual

View file

@ -70,12 +70,8 @@
<listitem><para>Units whose standard output or error output is connected to <option>journal</option> or
<option>kmsg</option> (or their combinations with console output, see below) automatically acquire
dependencies of type <varname>After=</varname> on <filename>systemd-journald.socket</filename>.
</para></listitem>
<listitem><para>Units using the terminal (standard input, output, or error are connected to a terminal
or <varname>TTYPath=</varname> is used) automatically acquire an <varname>After=</varname> dependency
on <filename>systemd-vconsole-setup.service</filename>.</para></listitem>
dependencies of type <varname>After=</varname> on
<filename>systemd-journald.socket</filename>.</para></listitem>
<listitem><para>Units using <varname>LogNamespace=</varname> will automatically gain ordering and
requirement dependencies on the two socket units associated with

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

View file

@ -86,7 +86,6 @@
#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service"
#define SPECIAL_QUOTAON_SERVICE "quotaon.service"
#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"
#define SPECIAL_VCONSOLE_SETUP_SERVICE "systemd-vconsole-setup.service"
#define SPECIAL_VOLATILE_ROOT_SERVICE "systemd-volatile-root.service"
#define SPECIAL_UDEVD_SERVICE "systemd-udevd.service"
#define SPECIAL_GROWFS_SERVICE "systemd-growfs@.service"

View file

@ -229,25 +229,34 @@ static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows,
}
static void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
const char *path;
_cleanup_close_ int fd = -EBADF;
const char *path = exec_context_tty_path(ASSERT_PTR(context));
assert(context);
/* Take a lock around the device for the duration of the setup that we do here.
* systemd-vconsole-setup.service also takes the lock to avoid being interrupted.
* We open a new fd that will be closed automatically, and operate on it for convenience.
*/
path = exec_context_tty_path(context);
if (p && p->stdin_fd >= 0) {
fd = xopenat_lock(p->stdin_fd, NULL,
O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0, 0, LOCK_BSD, LOCK_EX);
if (fd < 0)
return;
} else if (path) {
fd = open_terminal(path, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return;
if (context->tty_vhangup) {
if (p && p->stdin_fd >= 0)
(void) terminal_vhangup_fd(p->stdin_fd);
else if (path)
(void) terminal_vhangup(path);
}
if (lock_generic(fd, LOCK_BSD, LOCK_EX) < 0)
return;
} else
return; /* nothing to do */
if (context->tty_reset) {
if (p && p->stdin_fd >= 0)
(void) reset_terminal_fd(p->stdin_fd, true);
else if (path)
(void) reset_terminal(path);
}
if (context->tty_vhangup)
(void) terminal_vhangup_fd(fd);
if (context->tty_reset)
(void) reset_terminal_fd(fd, true);
if (p && p->stdin_fd >= 0) {
unsigned rows = context->tty_rows, cols = context->tty_cols;
@ -7180,16 +7189,6 @@ bool exec_context_has_encrypted_credentials(ExecContext *c) {
return false;
}
int exec_context_add_default_dependencies(Unit *u, const ExecContext *c) {
assert(u);
assert(u->default_dependencies);
if (c && exec_context_needs_term(c))
return unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_VCONSOLE_SETUP_SERVICE,
/* add_reference= */ true, UNIT_DEPENDENCY_DEFAULT);
return 0;
}
void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);

View file

@ -501,7 +501,6 @@ void exec_context_revert_tty(ExecContext *c);
int exec_context_get_clean_directories(ExecContext *c, char **prefix, ExecCleanMask mask, char ***ret);
int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret);
int exec_context_add_default_dependencies(Unit *u, const ExecContext *c);
void exec_status_start(ExecStatus *s, pid_t pid);
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);

View file

@ -601,7 +601,7 @@ static int mount_add_default_dependencies(Mount *m) {
if (r < 0)
return r;
return exec_context_add_default_dependencies(UNIT(m), &m->exec_context);
return 0;
}
static int mount_verify(Mount *m) {

View file

@ -747,12 +747,7 @@ static int service_add_default_dependencies(Service *s) {
return r;
/* Third, add us in for normal shutdown. */
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
if (r < 0)
return r;
/* Fourth, add generic dependencies */
return exec_context_add_default_dependencies(UNIT(s), &s->exec_context);
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
}
static void service_fix_stdio(Service *s) {

View file

@ -283,11 +283,7 @@ static int socket_add_default_dependencies(Socket *s) {
return r;
}
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
if (r < 0)
return r;
return exec_context_add_default_dependencies(UNIT(s), &s->exec_context);
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
}
_pure_ static bool socket_has_exec(Socket *s) {

View file

@ -270,11 +270,7 @@ static int swap_add_default_dependencies(Swap *s) {
if (r < 0)
return r;
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
if (r < 0)
return r;
return exec_context_add_default_dependencies(UNIT(s), &s->exec_context);
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
}
static int swap_verify(Swap *s) {

View file

@ -145,12 +145,11 @@ bool is_clean_exit(int code, int status, ExitClean clean, const ExitStatusSet *s
bitmap_isset(&success_status->status, status));
/* If a daemon does not implement handlers for some of the signals, we do not consider this an
unclean shutdown */
* unclean shutdown */
if (code == CLD_KILLED)
return
(clean == EXIT_CLEAN_DAEMON && IN_SET(status, SIGHUP, SIGINT, SIGTERM, SIGPIPE)) ||
(success_status &&
bitmap_isset(&success_status->signal, status));
return (clean == EXIT_CLEAN_DAEMON && IN_SET(status, SIGHUP, SIGINT, SIGTERM, SIGPIPE)) ||
(success_status &&
bitmap_isset(&success_status->signal, status));
return false;
}

View file

@ -26,6 +26,7 @@
#include "fileio.h"
#include "io-util.h"
#include "locale-util.h"
#include "lock-util.h"
#include "log.h"
#include "proc-cmdline.h"
#include "process-util.h"
@ -589,6 +590,14 @@ int main(int argc, char **argv) {
context_load_config(&c);
/* Take lock around the remaining operation to avoid being interrupted by a tty reset operation
* performed for services with TTYVHangup=yes. */
r = lock_generic(fd, LOCK_BSD, LOCK_EX);
if (r < 0) {
log_error_errno(r, "Failed to lock console: %m");
return EXIT_FAILURE;
}
(void) toggle_utf8_sysfs(utf8);
(void) toggle_utf8_vc(vc, fd, utf8);

View file

@ -15,7 +15,14 @@ ConditionPathIsReadWrite=/etc
ConditionFirstBoot=yes
DefaultDependencies=no
After=systemd-remount-fs.service systemd-sysusers.service systemd-tmpfiles-setup.service
# This service may need to write to the file system:
After=systemd-remount-fs.service
# Both systemd-sysusers and systemd-tmpfiles may create the root account
# (via factory files or credentials), obviating the need for us to do that:
After=systemd-sysusers.service systemd-tmpfiles-setup.service
# Let vconsole-setup do its setup before starting user interaction:
After=systemd-vconsole-setup.service
Wants=first-boot-complete.target
Before=first-boot-complete.target sysinit.target
Conflicts=shutdown.target

View file

@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
Description=Setup Virtual Console
Description=Virtual Console Setup
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
ConditionPathExists=/dev/tty0
@ -19,6 +19,12 @@ Before=initrd-switch-root.target shutdown.target
[Service]
Type=oneshot
# This service will be restarted by udev whenever a new vtcon device appears.
# If the previous instance is still running, it shall be interrupted without
# error.
SuccessExitStatus=SIGTERM
RemainAfterExit=yes
ExecStart={{ROOTLIBEXECDIR}}/systemd-vconsole-setup
ImportCredential=vconsole.*