Here is a patch to debian-installer to enable it to run D-I on all available consoles.
This is one part of making arm64 machines work 'just like PCs' in the installer. I have also done some work on getting the graphical installer working. I have enabled that, but input is not working yet, so 'more later' on that. The multiple-console support involves a major revamp of 'reopen-consoles-linux' in rootskel in debian-installer, to get rid of a load of old cruft, and use /proc/consoles (i.e. the kernel's list) to choose the set of enabled consoles, running the startup rc scripts on just one console (to avoid doing things twice), then running debian-installer itself on all the consoles that are enabled and have device files. More details are available in the thread steve linked to on debian-boot. It seems like there is actually a cleaner way to do this, by getting init to do the heavy process/session/parallel-tasks lifting (instead of reopen-consoles and steal-ctty). I have a proof-of-concept patch for that, but it's not actually working right yet. I'll send that in when it does if I don't hit any roadblocks. Wookey -- Principal hats: Linaro, Debian, Wookware, ARM http://wookware.org/
diff --git a/src/etc/inittab-linux b/src/etc/inittab-linux index a7b8a23..437e208 100644 --- a/src/etc/inittab-linux +++ b/src/etc/inittab-linux @@ -5,7 +5,7 @@ ::sysinit:/sbin/reopen-console /sbin/debian-installer-startup # main setup program -::respawn:/sbin/reopen-console /sbin/debian-installer +::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 3287dd0..e13bfa3 100755 --- a/src/sbin/reopen-console-linux +++ b/src/sbin/reopen-console-linux @@ -1,74 +1,68 @@ #!/bin/sh # In order to give proper access to the tty, we need to locate the device -# corresponding to the console we are actually using. +# corresponding to each console we are actually using. + +# 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) + NL=" " -console= -if ! [ -f /var/run/console-device ]; then - # If the kernel emitted a "handover" message, then it's the one - case $(uname -r) in - 2.6.2*|2.6.3[01]*) - console="$(dmesg -s 262143 | - sed -n -r -e 's/(.*\])? *console handover: boot \[.*\] -> real \[(.*)\]$/\2/p')" - ;; - 2.6.3[234567]*) - console="$(dmesg -s 262143 | - sed -n -r -e 's/(.*\])? *console \[(.*)\] enabled, bootconsole disabled$/\2/p')" - ;; - *) # >= 2.6.38 - console_major_minor="$(get-real-console-linux)" - console_raw="$(readlink "/sys/dev/char/${console_major_minor}")" - console="${console_raw##*/}" - ;; - esac - - # Except if it is the wrong type... - if [ "$console" ] && [ "$(console-type)" = serial ] && \ - expr "$console" : "tty[0-9]" >/dev/null; then - console= - fi +if ! [ -f /var/run/console-devices ]; then consoles= - if [ -z "$console" ]; then - # Retrieve all enabled consoles from boot log; ignore those - # for which no device file exists - for cons in $(dmesg -s 262143 | - sed -n -r -e 's/(.*\])? *console \[(.*)\] enabled/\2/p') - do - if [ -e "/dev/$cons" ]; then - consoles="${consoles:+$consoles$NL}$cons" - fi - done - # Only one console? Then we are good. - if [ $(echo "$consoles" | wc -l) -eq 1 ]; then - console="$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 + 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 - fi + # 'C' console is 'most prefered'. + if [ $(echo "$status" | grep -o 'C') ]; then + preferred="$cons" + fi + done - if [ -z "$console" ]; then - # Locate the last enabled console present on the command line - for arg in $(cat /proc/cmdline); do - case $arg in - console=*) - arg=${arg#console=} - cons=${arg%%,*} - if echo "$consoles" | grep -q "^$cons$"; then - console=$cons - fi - ;; - esac - done + if [ -z "$consoles" ]; then + # Nothing found? Default to /dev/console. + consoles=console fi - - if [ -z "$console" ]; then - # Still nothing? Default to /dev/console. - console=console + if [ -z "$preferred" ]; then + #None marked preferred? Use the first one + preferred=$(echo "$consoles" | head -n 1) fi - echo /dev/$console > /var/run/console-device + + for cons in $consoles + do + echo "/dev/$cons " >> /var/run/console-devices + done + echo "/dev/$preferred " > /var/run/console-preferred fi -# Some other session may have it as ctty. Steal it from them -exec /sbin/steal-ctty $(cat /var/run/console-device) "$@" +# 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 "$@" +fi + + diff --git a/src/sbin/steal-ctty.c b/src/sbin/steal-ctty.c index 0f3b14f..b99c1bb 100644 --- a/src/sbin/steal-ctty.c +++ b/src/sbin/steal-ctty.c @@ -28,8 +28,14 @@ int main(int argc, char ** argv) while (fd > 2) { close(fd--); } - ioctl(0, TIOCSCTTY, (char *) 1); - execvp(argv[2], &argv[2]); + /* make controlling tty if possible - can't be done if D-I is + run on multiple consoles so just quietly move on */ + if (-1 == ioctl(0, TIOCSCTTY, (char *) 1)) { + } + if (-1 == execvp(argv[2], &argv[2])) { + perror("execvp"); + return 1; + } /* never reached. */ return 0; }
signature.asc
Description: PGP signature