From c2060e8a731a2146c025992bc418c104bfcc4712 Mon Sep 17 00:00:00 2001 From: "Gerd v. Egidy" Date: Sun, 24 Apr 2022 18:48:49 +0200 Subject: [PATCH] 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" --- .../systemd/scripts/sysrescue-initialize.py | 28 ++++++++-- .../template/serial-autoterminal.service | 54 +++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 airootfs/usr/share/sysrescue/template/serial-autoterminal.service diff --git a/airootfs/etc/systemd/scripts/sysrescue-initialize.py b/airootfs/etc/systemd/scripts/sysrescue-initialize.py index 644f228..e02daa5 100755 --- a/airootfs/etc/systemd/scripts/sysrescue-initialize.py +++ b/airootfs/etc/systemd/scripts/sysrescue-initialize.py @@ -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 - print (f"setting terminal '{terminal}' to '{command}'") + 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 - conf_data=conf_template.replace("%TTY%",terminal) + 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 - symlink_overwrite("/dev/null",f"/etc/systemd/system/getty@{terminal}.service") - symlink_overwrite("/dev/null",f"/etc/systemd/system/autovt@{terminal}.service") + 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"]) diff --git a/airootfs/usr/share/sysrescue/template/serial-autoterminal.service b/airootfs/usr/share/sysrescue/template/serial-autoterminal.service new file mode 100644 index 0000000..c5a7bcb --- /dev/null +++ b/airootfs/usr/share/sysrescue/template/serial-autoterminal.service @@ -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