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 <woo...@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
signature.asc
Description: PGP signature