On 2019-02-09 04:11 +0000, Wookey wrote: > Future work: > > All this faffage has made me realise that a better approach to all > this would probably be to get rid of all this 'steal-ctty' bodgery, > and use init to do it's job: it's designed to run multiple things on > multiple consoles, and deal with file handles and them failing etc. > > The catch is that to make this work we'd have to use sysinit: to run > the console-choosing code, then write a new inittab containing one > respawn:/sbin/debian-installer for each console instance, then HUP > init. This should do exactly the right thing (assuming that busybox > init isn't too thick to get HUPing right). OK. This does indeed work nicely and is a cleaner solution than what is currently in D-I. It probably works for hurd and bsd too assuming their init behaviour is similar? (I think kill -HUP 1 should do the same thing on all 3 kernels?) (anyone up for testing these?) So now inittab looks like: # main rc script ::sysinit:/sbin/reopen-console /sbin/debian-installer-startup # main setup program tty0::respawn:/sbin/debian-installer ttyAMA0::respawn:/sbin/debian-installer (these lines added for whatever consoles are found) (and the rest as before - spare shells, tty4 for logging and restart stuff) Attached is a patch implementing this. It does rely on the inittab comment '# main setup program' existing in order to anchor the sed edit, so perhaps a comment should go in there so someone doesn't accidentally edit it in the future and break this code? Or we could just use a simple append (it's not aesthetic just putting them on the end but it does work fine), or just 'insert at line n'. Given the constrained environment I don't think it matters much - maintainability is probably the most important thing here. Steal-ctty is still present for the initial run of the debian-install-startup scripts but I suspect it's not actually needed. Anyone know if there was ever a good reason for running the rc scripts through this as well as doing so for the installer itself? This all works with netbook-gtk too (X starts on framebuffer, as before) Feedback on this patch is welcome. Note that my finish-install patch should be applied too if this one is used. Issues: The framebuffer console came up with some UTF-8 chars as blocks (ones not in 8859-1?). I've seen this before once with the old code then it went away again, so I'm not sure it's anything to do with these changes but it might be. The LANG=C.UTF-8, TERM=linux, TERM_TYPE=virtual, TERM_FRAMEBUFFER=yes, which seems reasonable. Clues welcome. fonts or TERM configuration? Further work: There is more tidying that could be done here, but some discussion is in order first. With things done this way 'reopen-console' is something of a misnomer as it only gets run once. 'choose-console' would be better. Or possibly something like 'initialise-installer' as it now chooses the consoles, calls the init-script runner and reinits to start the real installer. Perhaps a more logical split is choose-consoles: (OS-specific) 1) parses consoles, saves in /var/run files 2) runs debian-installer-startup debian-installer-startup: (OS-independent) 1) modifies inittab 2) runs startup scripts 3) HUPs init This seems a bit cleaner and better-named? Also is there any point having choose-console run $@ now there is only one thing it runs (debian-installer-startup)? The fly in this pointment is that there is one script that uses the existing /sbin/debian-installer-startup. That is debian-installer-launcher/debian-installer.sh which runs it in a live image chroot so moving the restart init there would be an unexpected change of interface. The desire to leave that interface alone results in this: choose-consoles: (OS-specific) 1) parses consoles, saves in /var/run files 2) modifies inittab 3) runs debian-installer-startup 4) HUPs init debian-installer-startup: (OS-independent) 1) runs startup scripts Which is essentially the existing patch, but renaming reopen-console -> choose-consoles currently we have: ::sysinit:/sbin/reopen-console /sbin/debian-installer-startup but I suggest we just change it to: ::sysinit:/sbin/choose-consoles and choose consoles can explicitly run /sbin/debian-installer-startup This just makes it a bit more obvious how things work/fit together. Have I missed anything? Does anyone care about all this? Shall I just stop now (it's working fine) or tidy a bit more to make the names clearer and reduce the cruft further? Wookey -- Principal hats: Linaro, Debian, Wookware, ARM http://wookware.org/
commit 7b3718082645c2265f96b8349ae25a31f3bc73e3
Author: Wookey <wookey@debian.org>
Date: Mon Feb 11 16:39:40 2019 +0000
Use inittab to run multiple installers
diff --git a/src/etc/inittab-linux b/src/etc/inittab-linux
index 437e208..830ee94 100644
--- a/src/etc/inittab-linux
+++ b/src/etc/inittab-linux
@@ -5,7 +5,6 @@
::sysinit:/sbin/reopen-console /sbin/debian-installer-startup
# main setup program
-::respawn:/sbin/reopen-console --all-consoles /sbin/debian-installer
# convenience shells
tty2::askfirst:-/bin/sh
diff --git a/src/sbin/reopen-console-linux b/src/sbin/reopen-console-linux
index 32dfd24..bd734ff 100755
--- a/src/sbin/reopen-console-linux
+++ b/src/sbin/reopen-console-linux
@@ -1,67 +1,67 @@
#!/bin/sh
-# In order to give proper access to the tty, we need to locate the device
-# corresponding to each console we are actually using.
+# First find the enabled consoles from the kernel, noting if one is 'preferred'
+# Record these.
+# Run the startup scripts on the preferred console
-# This script is run twice, once at sysinit to run the debian-installer-startup
-# rc scripts, and once to start the installer itself.
-# The first time it parses the consoles used, the second time they are read from files
-# The startup scripts need to be run just once (on one console) (not idempotent)
-# The installer is run on all the enabled consoles (using the --all-consoles option)
+# In order to have D-I appear on all consoles, edit the inittab to add one entry
+# for each console, running debian-installer.
+# Finally HUP init so that it runs those installers
+# (but doesn't rerun the sysinit startup stuff, including this script)
NL="
"
-if ! [ -f /var/run/console-devices ]; then
+consoles=
+preferred=
+# Retrieve all enabled consoles from kernel; ignore those
+# for which no device file exists
- consoles=
- preferred=
- # Retrieve all enabled consoles from kernel; ignore those
- # for which no device file exists
-
- kernelconsoles="$(cat /proc/consoles)"
- for cons in $(echo "$kernelconsoles" | sed -n -r -e 's/(^.*) .*\((.*)\).*$/\1/p' )
- do
- # prefer first console listed if none marked preferred
- if [ "$preferred" = "" ]; then
- preferred="$cons"
- fi
- status=$(echo "$kernelconsoles" | grep $cons | sed -n -r -e 's/(^.*) *.*\((.*)\).*$/\2/p' )
- if [ -e "/dev/$cons" ] && [ $(echo "$status" | grep -o 'E') ]; then
- consoles="${consoles:+$consoles$NL}$cons"
- fi
- # 'C' console is 'most prefered'.
- if [ $(echo "$status" | grep -o 'C') ]; then
- preferred="$cons"
- fi
- done
-
- if [ -z "$consoles" ]; then
- # Nothing found? Default to /dev/console.
- consoles=console
+kernelconsoles="$(cat /proc/consoles)"
+for cons in $(echo "$kernelconsoles" | sed -n -r -e 's/(^.*) .*\((.*)\).*$/\1/p' )
+do
+ status=$(echo "$kernelconsoles" | grep $cons | sed -n -r -e 's/(^.*) *.*\((.*)\).*$/\2/p' )
+ if [ -e "/dev/$cons" ] && [ $(echo "$status" | grep -o 'E') ]; then
+ consoles="${consoles:+$consoles$NL}$cons"
fi
- for cons in $consoles
- do
- echo "/dev/$cons " >> /var/run/console-devices
- done
- echo "/dev/$preferred " > /var/run/console-preferred
-fi
+ # 'C' console is 'most prefered'.
+ if [ $(echo "$status" | grep -o 'C') ]; then
+ preferred="$cons"
+ fi
+done
-# run startup scripts on one console, D-I itself on all consoles
-if [ "$1"x = "--all-consoles"x ]; then
- shift
- # Start d-i on each console.
- for cons in $(cat /var/run/console-devices)
- do
- /sbin/steal-ctty $cons "$@" &
- done
- #Don't respawn in init if running installer on multiple consoles
- sleep 2147483647 #'infinity' not supported in D-I busybox; 68 years will have to do
-else
- cons=$(cat /var/run/console-preferred)
- # Some other session may have console as ctty. Steal it from them
- exec /sbin/steal-ctty $cons "$@"
+if [ -z "$consoles" ]; then
+ # Nothing found? Default to /dev/console.
+ consoles=console
+fi
+if [ -z "$preferred" ]; then
+ #None marked preferred? Use the first one
+ preferred=$(echo "$consoles" | head -n 1)
fi
+for cons in $consoles
+do
+ echo "/dev/$cons " >> /var/run/console-devices
+done
+echo "/dev/$preferred " > /var/run/console-preferred
+
+
+#Add debian-installer lines into inittab - one per console
+inittab=
+for cons in $(cat /var/run/console-devices)
+do
+ DIline="${cons#/dev/}::respawn:/sbin/debian-installer"
+ inittab="${inittab:+$inittab$NL}$DIline"
+done
+
+echo "$inittab" > /tmp/initlines
+sed -i -e '/# main setup program/r /tmp/initlines' /etc/inittab
+
+#Run the startup scripts
+cons=$(cat /var/run/console-preferred)
+# Some other session may have console as ctty. Steal it from them
+/sbin/steal-ctty $cons "$@"
+#Finally restart init to run debian-installer on discovered consoles
+kill -HUP 1
Attachment:
signature.asc
Description: PGP signature