From 4d0966455f3bac8c23c535098dc844c6bad90b4a Mon Sep 17 00:00:00 2001 From: Mikhail Malyshev Date: Fri, 10 Jan 2025 15:42:22 +0100 Subject: [PATCH 1/4] Add /usr/bin/rungetty.sh - Add unmodified file to patch it following commit The script is taken from getty container from linux kit https://github.com/linuxkit/linuxkit/blob/master/pkg/getty/usr/bin/rungetty.sh Signed-off-by: Mikhail Malyshev --- pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh diff --git a/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh b/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh new file mode 100755 index 0000000000..61b5920e9e --- /dev/null +++ b/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +infinite_loop() { + while true; do + $@ + done +} + +# run getty on all known consoles +start_getty() { + tty=${1%,*} + speed=${1#*,} + securetty="$2" + line= + term="linux" + [ "$speed" = "$1" ] && speed=115200 + + # did we already process this tty? + if $(echo "${PROCESSEDTTY}" | grep -q -w "$tty"); then + echo "getty: already processed tty for $tty, not starting twice" | tee /dev/console + return + fi + # now indicate that we are processing it + PROCESSEDTTY="${PROCESSEDTTY} ${tty}" + + # does the device even exist? + if [ ! -c /dev/$tty ]; then + echo "getty: cmdline has console=$tty but /dev/$tty is not a character device; not starting getty for $tty" | tee /dev/console + return + fi + + case "$tty" in + ttyS*|ttyAMA*|ttyUSB*|ttyMFD*) + line="-L" + term="vt100" + ;; + tty?) + line="" + speed="38400" + term="" + ;; + esac + + # are we secure or insecure? + loginargs= + if [ "$INSECURE" == "true" ]; then + loginargs="-a root" + fi + + if ! grep -q -w "$tty" "$securetty"; then + # we could not find the tty in securetty, so start a getty but warn that root login will not work + echo "getty: cmdline has console=$tty but does not exist in $securetty; will not be able to log in as root on this tty $tty." | tee /dev/$tty + fi + # respawn forever + echo "getty: starting getty for $tty" | tee /dev/$tty + infinite_loop setsid.getty -w /sbin/agetty $loginargs $line $speed $tty $term & +} + + +# check if we are namespaced, and, if so, indicate in the PS1 +if [ -z "$INITGETTY" ]; then + cat >/etc/profile.d/namespace.sh <<"EOF" +export PS1="(ns: getty) $PS1" +EOF +fi + +PROCESSEDTTY= + +# check if we have /etc/getty.shadow +ROOTSHADOW=/hostroot/etc/getty.shadow +if [ -f $ROOTSHADOW ]; then + cp $ROOTSHADOW /etc/shadow + # just in case someone forgot a newline + echo >> /etc/shadow +fi + +for opt in $(cat /proc/cmdline); do + case "$opt" in + console=*) + start_getty ${opt#console=} /etc/securetty + esac +done + +# if we are in a container (not in root init) wait for all our child process to exit; tini will handle subreaping, if necessary +[ -n "$INITGETTY" ] || wait From 38b8e72eb664cf3bdf20233dd8bf28ce4c2f1cf5 Mon Sep 17 00:00:00 2001 From: Mikhail Malyshev Date: Fri, 10 Jan 2025 15:52:28 +0100 Subject: [PATCH 2/4] Replace tty0 with tty1 when starting getty 1) tty0 points to current virtual console. it is not a problem when getty is started very early before pillar/monitor are started however under following conditions it causes problems: 1. there is NO 'getty' specified on kernel command line 2. there is console=tty0 specified 3. debug.enable.console=true is set if all 3 are true then getty is started by pillar AFTER monitor app is started on tty2 and since tty0 points to tty2 in this case getty revokes console from monitor app and the output gets corrupted 2) we cannot use /dev/console from rungetty.sh anymore because it corrupts tty2 when running from pillar. Instead we use /dev/tty so the logs will be redirected to proper stdout and it should work in both cases: when getty is started by 'getty' parameter and when it is started from context of pillar. In later case logs will appear from pillar context which is correct Signed-off-by: Mikhail Malyshev --- pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh b/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh index 61b5920e9e..e69bd13501 100755 --- a/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh +++ b/pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh @@ -15,9 +15,18 @@ start_getty() { term="linux" [ "$speed" = "$1" ] && speed=115200 + # if console=tty0 is specified on the kernel command line, we should not start a getty on tty0 + # but instead start it on the first available tty. tty0 points to the current console, so if + # we start a getty from pillar of debug.enable.console=true we may start it on current tty + # which may be occupied by TUI monitor application and tty will be taken away by getty. + # replacing tty0 with tty1 should be ok because this is the user's intention + if [ "$tty" = "tty0" ]; then + tty="tty1" + fi + # did we already process this tty? if $(echo "${PROCESSEDTTY}" | grep -q -w "$tty"); then - echo "getty: already processed tty for $tty, not starting twice" | tee /dev/console + echo "getty: already processed tty for $tty, not starting twice" | tee /dev/tty return fi # now indicate that we are processing it @@ -25,7 +34,7 @@ start_getty() { # does the device even exist? if [ ! -c /dev/$tty ]; then - echo "getty: cmdline has console=$tty but /dev/$tty is not a character device; not starting getty for $tty" | tee /dev/console + echo "getty: cmdline has console=$tty but /dev/$tty is not a character device; not starting getty for $tty" | tee /dev/tty return fi From a993891ff0bbe445424448100bb6d3536c0ce341 Mon Sep 17 00:00:00 2001 From: Mikhail Malyshev Date: Fri, 10 Jan 2025 16:54:49 +0100 Subject: [PATCH 3/4] Add rungetty.sh to ignore lists for yetus We do not maintain this file so do not check for errors (too many of them really) Signed-off-by: Mikhail Malyshev --- .spdxignore | 1 + .yetus/blanks-tabs.txt | 1 + .yetus/excludes.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/.spdxignore b/.spdxignore index bb91ca940a..f3e8637e2b 100644 --- a/.spdxignore +++ b/.spdxignore @@ -14,3 +14,4 @@ pkg/kube/descheduler-job.yaml pkg/kube/descheduler_rbac.yaml pkg/kube/lh-cfg-v1.6.2.yaml pkg/vtpm/swtpm-vtpm/vendor/ +pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh diff --git a/.yetus/blanks-tabs.txt b/.yetus/blanks-tabs.txt index c2bcfc31b7..2776a3482b 100644 --- a/.yetus/blanks-tabs.txt +++ b/.yetus/blanks-tabs.txt @@ -3,3 +3,4 @@ .*\.dts .*\.md ^.codespellignorelines +pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh diff --git a/.yetus/excludes.txt b/.yetus/excludes.txt index 3532d23367..4313895c00 100644 --- a/.yetus/excludes.txt +++ b/.yetus/excludes.txt @@ -20,3 +20,4 @@ ^.+/testdata/.+ ^.codespellignorelines eve-tools/bpftrace-compiler/examples/.+\.bt +pkg/dom0-ztools/rootfs/usr/bin/rungetty.sh From ef304dfcd3add32dcb8d450039294f0336d6f51a Mon Sep 17 00:00:00 2001 From: Mikhail Malyshev Date: Mon, 13 Jan 2025 14:05:52 +0100 Subject: [PATCH 4/4] Update documentation for monitor TUI app - Add explanation for differences between /dev/tty0, /dev/console, and /dev/ttyX Signed-off-by: Mikhail Malyshev --- docs/LOCAL-TUI.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/LOCAL-TUI.md b/docs/LOCAL-TUI.md index f2f5867e31..873657e58c 100644 --- a/docs/LOCAL-TUI.md +++ b/docs/LOCAL-TUI.md @@ -12,13 +12,17 @@ The client communicates with the server over UNIX socket The UI is rendered on a local TTY (/dev/tty2) only i.e. on a physical monitor attached to the system. Neither Serial Console nor SSH connection has access to TUI. It is done to ensure the physical presence of the operator. -## /dev/ttyX vs /dev/console +## /dev/ttyX vs /dev/console vs /dev/tty0 -There are two distinguishable console devices in Linux `/dev/console` and `/dev/ttyX`. The later points to a particular virtual terminal device and the former points to *currently active* TTY device. The user can switch between virtual terminals by using `Alt+Fx` or `Alt+<,>` keys. When the current TTY is set `/dev/console` tracks this change and always points to to the current terminal +There are three distinguishable console devices in Linux `/dev/console`, `/dev/tty0` and `/dev/ttyX` where X > 0. The latter points to a particular virtual terminal device i.e. a dedicated framebuffer for VGA console. `/dev/tty0` points to *currently active* TTY device. This can be proven by reading `/sys/devices/virtual/tty/tty0/active` file. This file exists only for `/dev/tty0`. On the other hand `/dev/console` may point to several devices at a time. These are devices user specifies in `console=` kernel command line parameters. The list can be obtained by reading `/sys/devices/virtual/tty/console/active` file. -Monitor application is spawned on a `/dev/tty2` using a `openvt` utility while the rest of the applications are spawned on the default kernel console defined by `console=` parameters on the kernel command line. When the application is in focus (`/dev/tty2` is an active console) writing to `/dev/console` which points to the same device corrupts TUI thus it cannot be used by other services in the system to produce the output. At least when `/dev/tty2` is a current console. +The user can switch between virtual terminals by using `Alt+Fx` or `Alt+<,>` keys. When the current TTY is set `/dev/tty0` tracks this change and always points to to the current terminal -From the other hand `/dev/tty` (no digit at the end!) device always points to a TTY *in the context of running process*. This device can be used instead of `/dev/console` by other services for the output. +Monitor application is spawned on a `/dev/tty2` using a `openvt` utility while the rest of the applications are spawned on the default kernel console defined by `console=` parameters on the kernel command line. When the application is in focus (`/dev/tty2` is an active console) writing to `/dev/console` or to `/dev/tty0` which points to the same device corrupts TUI thus it cannot be used by other services in the system to produce the output. At least when `/dev/tty2` is a current console. + +On the other hand `/dev/tty` (no digit at the end!) device always points to a TTY *in the context of running process*. This device can be used instead of `/dev/console` by other services for the output. + +Mode details can be found in [https://www.kernel.org/doc/Documentation/admin-guide/serial-console.rst](https://www.kernel.org/doc/Documentation/admin-guide/serial-console.rst), [https://www.kernel.org/doc/html/v6.11/admin-guide/devices.html#virtual-consoles-and-the-console-device](https://www.kernel.org/doc/html/v6.11/admin-guide/devices.html#virtual-consoles-and-the-console-device) and in this blog post [https://www.baeldung.com/linux/monitor-keyboard-drivers](https://www.baeldung.com/linux/monitor-keyboard-drivers) ## Limitations of linux terminal