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

Re: Multiple console support in d-i



On 2019-01-23 08:35 +0000, Ian Campbell wrote:
> On Wed, 2019-01-23 at 03:41 +0000, Wookey wrote:

> > Any idea how we should choose a D-I primary console when none of them
> > is marked 'preferred'? Or should D-i do away with the concept and try
> > to treat them all equally (which is a slightly more intrusive
> > change).

> Even if the bug were fixed it seems sensible to deal with this case,
> last one (with sufficient other flags set) seems like as good as
> anything...

OK. I've had 'fun with shell' getting this right and gone through a 
couple of iterations.

After some thought, so far as I can see the 'preferred' console
concept is no longer useful once D-I runs on more than one. We don't
know which one the user is going to actually use, and the whole point
is that all the instances should work the same. We're not trying the
choose the 'right' console any more, just exposing the interface on
all the ones that (should) work.

The only reason for keeping it would be to keep the reopen-console
logic more like it currently is, so that the preferred console got to
replace the reopen-consoles process (via exec) and the others didn't
(becoming child processes of reopen-consoles dash instance). But you
end up with rather cleaner code if in fact you just run D-I on all enabled
consoles and treat them equivalently (as child processes). New version
(with debug still in) attached to show what I mean (or see below).

However this does lead to a question about D-I and inittab respawn logic.

Currently reopen-console ends with
exec D-I
so D-I replaces the process.

It is started with this inittab line:
::respawn:/sbin/reopen-console /sbin/debian-installer

Do we ever make use of D-I finishing in such a way that init finds the
process is gone and respawns? My assumption is that we don't want this
to happen, at least in general (otherwise the installer would restart
when you finished, rather confusingly). But perhaps there are error
cases when this is wanted?

The reason it matters is because it affects how the multiple D-Is on
different consoles should be started and what we should do when one
quits, or all quit.

My current code does this:
for cons in $(cat /var/run/console-devices)
do
        # Some other session may have console as ctty. Steal it from them
        ( exec /sbin/steal-ctty $cons "$@" & )
done
#don't return to init
sleep infinity

Which just starts a D-I on all the consoles, then sits forever (to
stop init from re-running this code over and over).  You _could_ have
some extra logic to make one special, and exec that one, and keep the
others as child-processes, but I'm not convinced that this achieves
anything (except complexity, and potentially confusingly different
behaviour between consoles), unless the respawning is important in
some way I have failed to grok so far?

(You'll note the above is rather nicer than my first effort with two
different /var/run/* files, and $console and $extraconsoles). Having
just the one 'consoles used' list file makes it all cleaner.  (I've
fixed up finish-install/finish-install.d/90console to deal with more
than one console listed in that file too)

Possibly what we'd really like is that if you quit _any_ console D-I
instance then it would return and respawn, but a) I can't work out how
to do that (you can only exec one thing) and b) does it actually help?

So, unless anyone can see a problem with this approach, I'll finish
this off. Trying to do it with separate /var/run/consoles and
/var/run/extra-consoles files was getting very messy. 

Wookey
-- 
Principal hats:  Linaro, Debian, Wookware, ARM
http://wookware.org/
#!/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.

NL="
"

if ! [ -f /var/run/console-devices ]; then

	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
		echo "cons in /proc/consoles: $cons"
		status=$(echo "$kernelconsoles" | grep $cons | sed -n -r -e 's/(^.*) *.*\((.*)\).*$/\2/p' )
		echo "console: $cons, status: $status"
		if [ -e "/dev/$cons" ] && [ $(echo "$status" | grep -o 'E') ]; then
			consoles="${consoles:+$consoles$NL}$cons"
		fi
		# 'C' console is 'most prefered'. Do we care?
		if [ $(echo "$status" | grep -o 'C') ]; then
			preferred="$cons"
		fi
	done
	echo "after parsing, consoles set to: $consoles"
	echo "after parsing, preferred is: $preferred"
	
	if [ -z "$consoles" ]; then
		# Nothing found? Default to /dev/console.
		consoles=console
	fi
	for cons in $consoles
	do
	    echo "/dev/$cons " >> /var/run/console-devices
	done
	echo "consoles set to: $consoles"
	echo "recorded as: $(cat /var/run/console-devices)"
fi

sleep 8
# Start provided args on each console.
for cons in $(cat /var/run/console-devices)
do
    # Some other session may have console as ctty. Steal it from them
	echo "Starting D-I on: $cons"
	( exec /sbin/steal-ctty $cons "$@" & )
	sleep 4
done
#don't return to init
sleep infinity

Attachment: signature.asc
Description: PGP signature


Reply to: