[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Multiple console support in d-i



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


Reply to: