implement handling of serial consoles for autoterminal

serial consoles have separate systemd services (serial-getty@.service). We need to adapt
the handling and also need some different options for them than for regular gettys.

To allow sysrescue-initialize.py to differentiate between regular consoles and serial ones
they must be configured with the prefix "serial:" in the yaml, for example like this:

autoterminal:
    "serial:ttyS0": "/usr/bin/bash"
This commit is contained in:
Gerd v. Egidy 2022-04-24 18:48:49 +02:00
parent c3b0b576a4
commit c2060e8a73
2 changed files with 78 additions and 4 deletions

View file

@ -208,27 +208,47 @@ if ('autoterminal' in config) and (config['autoterminal'] is not None) and \
print("====> Configuring autoterminal ...")
with open('/usr/share/sysrescue/template/autoterminal.service', 'r') as template_file:
conf_template = template_file.read()
with open('/usr/share/sysrescue/template/serial-autoterminal.service', 'r') as template_file:
serial_conf_template = template_file.read()
start_services = []
for terminal, command in sorted(config['autoterminal'].items()):
if m := re.match(r"^serial:([a-zA-Z0-9_-]+)$", terminal):
serial=True
terminal = m.group(1)
else:
serial=False
if not re.match(r"^[a-zA-Z0-9_-]+$", terminal):
print (f"Ignoring invalid terminal name '{terminal}'")
errcnt+=1
continue
# do not check if terminal or command exists: an autorun could create them later on
if serial:
print (f"setting serial terminal '{terminal}' to '{command}'")
else:
print (f"setting terminal '{terminal}' to '{command}'")
with open(f"/etc/systemd/system/autoterminal-{terminal}.service", "w") as terminal_conf:
# write service config, based on the template config we loaded above
# don't use getty@{terminal}.service name to not use autovt@{terminal}.service on-demand logic
if serial:
conf_data=serial_conf_template.replace("%TTY%",terminal)
else:
conf_data=conf_template.replace("%TTY%",terminal)
conf_data=conf_data.replace("%EXEC%",command)
terminal_conf.write(conf_data)
# enable service: always start it, do not wait for the user to switch to the terminal
# means other programs (like X.org) can't allocate it away, also allows for longer running init sequences
symlink_overwrite(f"/etc/systemd/system/autoterminal-{terminal}.service",
f"/etc/systemd/system/getty.target.wants/autoterminal-{terminal}.service")
# mask the regular getty for this terminal
if serial:
symlink_overwrite("/dev/null",f"/etc/systemd/system/serial-getty@{terminal}.service")
else:
symlink_overwrite("/dev/null",f"/etc/systemd/system/getty@{terminal}.service")
symlink_overwrite("/dev/null",f"/etc/systemd/system/autovt@{terminal}.service")
start_services.append(f"autoterminal-{terminal}.service")
# reload systemd to allow the new config to take effect
subprocess.run(["/usr/bin/systemctl", "daemon-reload"])

View file

@ -0,0 +1,54 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of SystemRescue, based on serial-getty@.service from systemd
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=SystemRescue serial autoterminal %TTY%
Documentation=https://www.system-rescue.org/manual/autoterminal/
BindsTo=dev-%TTY%.device
After=dev-%TTY%.device systemd-user-sessions.service plymouth-quit-wait.service \
getty-pre.target serial-getty@%TTY%.service
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes
# IgnoreOnIsolate causes issues with sulogin, if someone isolates
# rescue.target or starts rescue.service from multi-user.target or
# graphical.target.
Conflicts=rescue.service serial-getty@%TTY%.service
Before=rescue.service
[Service]
ExecStart=-%EXEC%
# do not wait 5 seconds as for Type=idle before starting the service
Type=simple
Restart=always
RestartSec=1
UtmpIdentifier=%TTY%
StandardInput=tty
StandardOutput=tty
TTYPath=/dev/%TTY%
TTYReset=yes
TTYVHangup=yes
IgnoreSIGPIPE=no
SendSIGHUP=yes
# make this a systemd-logind session without needing a getty
User=root
PAMName=login
# generate all utmp/wtmp entries and don't expect the program to do it
UtmpMode=user
[Install]
WantedBy=getty.target