Previously, the active consoles were only checked once, so if a console appeared later, getty wouldn't be run for it. This meant that if the console was set to a serial device whose driver was not built-in, it might have no shell if the module was not loaded until after rc.init had already run. Also, if a console device was removed, its instance of the serial-getty would hang around. To fix this, replace the getty instantiation in rc.init with a service that will create and destroy serial-getty instances to match the currently configured consoles, which will rerun whenever the configured consoles change. Fixes: b096279 ("host/rootfs: run getty for active serial consoles") Signed-off-by: Alyssa Ross <hi@alyssa.is> --- host/rootfs/Makefile | 1 + host/rootfs/default.nix | 8 ++-- .../service/serial-getty-generator/run | 43 +++++++++++++++++++ host/rootfs/etc/s6-linux-init/scripts/rc.init | 9 ---- 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100755 host/rootfs/etc/s6-linux-init/run-image/service/serial-getty-generator/run diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile index d54538b..d5b9b55 100644 --- a/host/rootfs/Makefile +++ b/host/rootfs/Makefile @@ -31,6 +31,7 @@ FILES = \ etc/s6-linux-init/run-image/service/getty-tty4/run \ etc/s6-linux-init/run-image/service/s6-svscan-log/notification-fd \ etc/s6-linux-init/run-image/service/s6-svscan-log/run \ + etc/s6-linux-init/run-image/service/serial-getty-generator/run \ etc/s6-linux-init/run-image/service/serial-getty/notification-fd \ etc/s6-linux-init/run-image/service/serial-getty/run \ etc/s6-linux-init/run-image/service/serial-getty/template/run \ diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix index b50d090..bfc1ba8 100644 --- a/host/rootfs/default.nix +++ b/host/rootfs/default.nix @@ -9,8 +9,8 @@ pkgsStatic.callPackage ( { start-vmm , lib, stdenvNoCC, nixos, runCommand, writeClosure, erofs-utils, s6-rc , bcachefs-tools, busybox, cloud-hypervisor, cryptsetup, dbus, execline -, e2fsprogs, inkscape, jq, kmod, mdevd, s6, s6-linux-init, socat -, util-linuxMinimal, virtiofsd, xorg +, e2fsprogs, inkscape, inotify-tools, jq, kmod, mdevd, s6 +, s6-linux-init, socat, util-linuxMinimal, virtiofsd, xorg , xdg-desktop-portal-spectrum-host }: @@ -137,8 +137,8 @@ let foot = pkgsGui.foot.override { allowPgo = false; }; packages = [ - bcachefs-tools cloud-hypervisor dbus execline jq kmod mdevd s6 - s6-linux-init s6-rc socat start-vmm virtiofsd + bcachefs-tools cloud-hypervisor dbus execline inotify-tools jq + kmod mdevd s6 s6-linux-init s6-rc socat start-vmm virtiofsd xdg-desktop-portal-spectrum-host (cryptsetup.override { diff --git a/host/rootfs/etc/s6-linux-init/run-image/service/serial-getty-generator/run b/host/rootfs/etc/s6-linux-init/run-image/service/serial-getty-generator/run new file mode 100755 index 0000000..445604f --- /dev/null +++ b/host/rootfs/etc/s6-linux-init/run-image/service/serial-getty-generator/run @@ -0,0 +1,43 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2+ +# SPDX-FileCopyrightText: 2024-2025 Alyssa Ross <hi@alyssa.is> + +piperw 3 4 +background { + fdclose 3 + fdmove 2 4 + inotifywait -e MODIFY /sys/class/tty/console/active +} +fdclose 4 +importas -i inotifywait_pid ! + +foreground { + if { fdmove 0 3 grep -qx "Watches established." } + background { fdmove 0 3 cat } + fdclose 3 + + # Wait until inotifywait is ready before updating serial gettys, + # so that changes won't be missed in between updating and starting + # inotifywait. + pipeline { s6-instance-list /run/service/serial-getty } + pipeline { sort } + fdmove -c 3 0 + + redirfd -r 0 /sys/class/tty/console/active + pipeline { tr " " "\n" } + pipeline { sort } + + pipeline { comm -3 - /proc/self/fd/3 } + forstdin -Ep line + case -N $line { + " ?tty[0-9]*" { } + " (.*)" { + importas -i tty 1 + s6-instance-delete /run/service/serial-getty $tty + } + } + s6-instance-create /run/service/serial-getty $line +} + +# Block until the active consoles change, then let s6 restart us. +wait -- $inotifywait_pid diff --git a/host/rootfs/etc/s6-linux-init/scripts/rc.init b/host/rootfs/etc/s6-linux-init/scripts/rc.init index c778714..674fd38 100755 --- a/host/rootfs/etc/s6-linux-init/scripts/rc.init +++ b/host/rootfs/etc/s6-linux-init/scripts/rc.init @@ -2,15 +2,6 @@ # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2020-2022, 2024 Alyssa Ross <hi@alyssa.is> -background { - redirfd -r 0 /sys/class/tty/console/active - withstdinas active - importas -isu active active - forx -po0 -E tty { $active } - case $tty { tty[0-9]* { } } - s6-instance-create /run/service/serial-getty $tty -} - if { s6-rc-init -c /etc/s6-rc /run/service } if { mount --make-shared /run } -- 2.49.0