From 4c76e8f05034528addcb9dda00f0ee7cf2837b89 Mon Sep 17 00:00:00 2001 From: Mike Hibler Date: Mon, 9 May 2016 16:06:30 -0600 Subject: [PATCH] You can now interact with grub on the d430s! Apparently, specifying "--unit==1" to grub did not work because grub didn't think it had a unit 1 (aka, COM2), so it rejected the "serial" command. Output still worked due to redirection (I think), but it was expecting input from the keyboard. It looks like the number of valid serial ports is compiled into grub and who knows how it was built for Ubuntu. Anyway, by specifying "--port=0x2F8" in addition, that will override the unit test and all is well. Strange. Also enhanced the Linux slicefix to deal with fixing /etc/default/grub so that those wacky console settings will remain in effect even if grub is re-configured (which some packages do). --- clientside/tmcc/freebsd/slicefix | 127 ++++++++++++++---------- clientside/tmcc/linux/linux_slicefix.pl | 87 +++++++++++++++- clientside/tmcc/linux/prepare | 8 +- 3 files changed, 167 insertions(+), 55 deletions(-) diff --git a/clientside/tmcc/freebsd/slicefix b/clientside/tmcc/freebsd/slicefix index 0cb2ce2ad..6a4712aa3 100755 --- a/clientside/tmcc/freebsd/slicefix +++ b/clientside/tmcc/freebsd/slicefix @@ -194,6 +194,23 @@ if [ $CONSOLE = "unknown" ]; then CONSOLE=sio1 fi +# Console ISA port +PORT= +case $CONSOLE in +sio1) + PORT="0x3F8" + ;; +sio2) + PORT="0x2F8" + ;; +sio3) + PORT="0x3E8" + ;; +sio4) + PORT="0x2E8" + ;; +esac + # DOM0MEM is optional DOM0MEM=$SLICEFIX_DOM0MEM @@ -652,25 +669,21 @@ EOF0 sio1) cname="comconsole" unit=0 - port=0x3F8 irq=4 ;; sio2) cname="comconsole" unit=1 - port=0x2F8 irq=3 ;; sio3) cname="comconsole" unit=2 - port=0x3E8 irq=5 ;; sio4) cname="comconsole" unit=3 - port=0x2E8 irq=9 ;; esac @@ -704,14 +717,14 @@ EOF1 if [ $drv != "none" ]; then # put in the new info cat <>/mnt/boot/loader.conf -comconsole_port="$port" +comconsole_port="$PORT" comconsole_speed="$SPEED" hint.$drv.0.flags="0x0" hint.$drv.1.flags="0x0" hint.$drv.2.flags="0x0" hint.$drv.3.flags="0x0" hint.$drv.$unit.at="isa" -hint.$drv.$unit.port="$port" +hint.$drv.$unit.port="$PORT" hint.$drv.$unit.irq="$irq" hint.$drv.$unit.flags="0x10" hint.$drv.$unit.disabled="0" @@ -1109,7 +1122,14 @@ dolinux() { # terminal_input serial # grub2 # terminal_output serial # grub2 # + # XXX we have a situation where SOL redirection puts the console + # at --unit=1, but grub does not recognize that as a valid unit + # and the result is that grub does not accept console input. + # But if we specify --port=0x2F8 it works fine. So we put both + # (this is documented, --port takes precedence). + # echo " setting console to $CONSOLE" + pstr="" case $CONSOLE in null|vid) # comment out any "serial" line @@ -1167,8 +1187,13 @@ dolinux() { u=`expr ${CONSOLE#sio} - 1` s=$SPEED + # XXX we only put in the --port=NNN option if this is grub2 + if grep -q '^terminal_input' $tgconf 2>/dev/null; then + pstr="--port=$PORT" + fi + # put back the "serial" line - sstr="serial --unit=$u --speed=$s" + sstr="serial --unit=$u $pstr --speed=$s" if ! grep -q -- "^$sstr" $tgconf 2>/dev/null; then sed -E -i '' -e "s;^#?serial.*;$sstr;" $tgconf fi @@ -1248,60 +1273,62 @@ dolinux() { fi rm -f $tgconf fi - fi - # - # Handle default settings file for grub since package installation - # might cause the grub.cfg file to get recreated. - # - # We just append variable definitions to the end of the file and - # override any existing settings. This would only adversely affect the - # GRUB_CMDLINE_LINUX param if it was being used for some other options. - # For vid or null we add: - # - # GRUB_CMDLINE_LINUX="console=tty0" - # GRUB_TERMINAL=console - # GRUB_SERIAL_COMMAND="" - # - # and for sio[1-3] we add: - # - # GRUB_CMDLINE_LINUX="console=ttySN,S" - # GRUB_TERMINAL=serial - # GRUB_SERIAL_COMMAND="serial --speed=S --unit=N" - # - gdef="/mnt/etc/default/grub" - if [ -e "$gdef" ]; then - echo " updating /etc/default/grub" - echo " setting console to $CONSOLE" - esig="# The remaining lines were added by Emulab slicefix" - if ! grep -q "^$esig" $gdef; then - cp -p $gdef $gdef.preemulab - else - sed -i '' -e "/^$esig/,$$d" $gdef - fi - cat <>$gdef + # + # Handle default settings file for grub since package installation + # might cause the grub.cfg file to get recreated. + # + # We just append variable definitions to the end of the file and + # override any existing settings. This would only adversely affect + # the GRUB_CMDLINE_LINUX param if it was being used for some other + # options. + # + # For vid or null we add: + # + # GRUB_CMDLINE_LINUX="console=tty0" + # GRUB_TERMINAL=console + # GRUB_SERIAL_COMMAND="" + # + # and for sio[1-3] we add: + # + # GRUB_CMDLINE_LINUX="console=ttySN,S" + # GRUB_TERMINAL=serial + # GRUB_SERIAL_COMMAND="serial --speed=S --unit=N" + # + gdef="/mnt/etc/default/grub" + if [ -e "$gdef" ]; then + echo " updating /etc/default/grub" + echo " setting console to $CONSOLE" + esig="# The remaining lines were added by Emulab slicefix" + if ! grep -q "^$esig" $gdef; then + cp -p $gdef $gdef.preemulab + else + sed -i '' -e "/^$esig/,$$d" $gdef + fi + cat <>$gdef $esig # DO NOT ADD ANYTHING AFTER THIS POINT AS IT WILL GET REMOVED. EOF5 - case $CONSOLE in - null|vid) - cat <>$gdef + case $CONSOLE in + null|vid) + cat <>$gdef GRUB_CMDLINE_LINUX="console=tty0" GRUB_TERMINAL=console GRUB_SERIAL_COMMAND="" EOF6 - ;; - sio*) - u=`expr ${CONSOLE#sio} - 1` - s=$SPEED - cat <>$gdef + ;; + sio*) + u=`expr ${CONSOLE#sio} - 1` + s=$SPEED + cat <>$gdef GRUB_CMDLINE_LINUX="console=ttyS$u,$s" GRUB_TERMINAL=serial -GRUB_SERIAL_COMMAND="serial --speed=$s --unit=$u" +GRUB_SERIAL_COMMAND="serial --unit=$u $pstr --speed=$s" EOF7 - ;; - esac - needfsck=1 + ;; + esac + needfsck=1 + fi fi # diff --git a/clientside/tmcc/linux/linux_slicefix.pl b/clientside/tmcc/linux/linux_slicefix.pl index e7d6f5d83..233660247 100755 --- a/clientside/tmcc/linux/linux_slicefix.pl +++ b/clientside/tmcc/linux/linux_slicefix.pl @@ -855,7 +855,7 @@ sub update_random_seed sub fix_console { - my ($imageroot, $file) = @_; + my ($imageroot, $bloader, $file) = @_; my $console = $ENV{"SLICEFIX_CONSOLE"}; if (!$console) { @@ -873,11 +873,18 @@ sub fix_console } my $sunit = -1; + my $sport = ""; if ($console =~ /^sio(\d+)$/) { $sunit = ($1 > 1) ? $1 - 1 : 0; + + if ($bloader eq 'grub2' && $sunit < 4) { + my @smap = ("0x3F8", "0x2F8", "0x3E8", "0x2E8"); + $sport = $smap[$sunit]; + } } - fix_grub_console($imageroot, $file, $console, $sunit, $sspeed); + fix_grub_console($imageroot, $file, $console, $sunit, $sspeed, $sport); + fix_grub_defaults($imageroot, $console, $sunit, $sspeed, $sport); # XXX we don't bother with /etc/inittab, only RHLnn-STD used it @@ -921,9 +928,79 @@ sub fix_console } } +# +# Handle default settings file for grub since package installation +# might cause the grub.cfg file to get recreated. +# +# We just append variable definitions to the end of the file and +# override any existing settings. This would only adversely affect the +# GRUB_CMDLINE_LINUX param if it was being used for some other options. +# For vid or null we add: +# +# GRUB_CMDLINE_LINUX="console=tty0" +# GRUB_TERMINAL=console +# GRUB_SERIAL_COMMAND="" +# +# and for sio[1-3] we add: +# +# GRUB_CMDLINE_LINUX="console=ttySN,S" +# GRUB_TERMINAL=serial +# GRUB_SERIAL_COMMAND="serial --speed=S --unit=N" +# +sub fix_grub_defaults +{ + my ($imageroot, $console, $sunit, $sspeed, $sport) = @_; + my $gdef = "$imageroot/etc/default/grub"; + + if (! -e $gdef) { + return; + } + if (! -e "$gdef.preemulab") { + system("cp -p $gdef $gdef.preemulab"); + } + + if (!open(FILE, "+<$gdef")) { + return; + } + + my $esig = "# The remaining lines were added by Emulab slicefix"; + + my @buffer = (); + while () { + if (/^$esig/) { + last; + } + push @buffer, $_; + } + + # append our info + push @buffer, "$esig\n"; + push @buffer, "# DO NOT ADD ANYTHING AFTER THIS POINT AS IT WILL GET REMOVED.\n"; + if ($sunit < 0) { + push @buffer, "GRUB_CMDLINE_LINUX=\"console=tty0\"\n"; + push @buffer, "GRUB_TERMINAL=console\n"; + push @buffer, "GRUB_SERIAL_COMMAND=\"\"\n"; + } else { + push @buffer, "GRUB_CMDLINE_LINUX=\"console=ttyS$sunit,$sspeed\"\n"; + push @buffer, "GRUB_TERMINAL=serial\n"; + if ($sport) { + push @buffer, "GRUB_SERIAL_COMMAND=\"serial --unit=$sunit --port=$sport --speed=$sspeed\"\n"; + } else { + push @buffer, "GRUB_SERIAL_COMMAND=\"serial --unit=$sunit --speed=$sspeed\"\n"; + } + } + + seek FILE, 0, 0; + truncate FILE, 0; + + print FILE @buffer; + + close FILE; +} + sub fix_grub_console { - my ($imageroot, $file, $console, $sunit, $sspeed) = @_; + my ($imageroot, $file, $console, $sunit, $sspeed, $sport) = @_; my $comunit = $sunit + 1; open FILE, "+<$imageroot/$file" || @@ -944,6 +1021,8 @@ sub fix_grub_console } else { push @buffer, "#$_"; } + } elsif ($sport) { + push @buffer, "serial --unit=$sunit --port=$sport --speed=$sspeed\n"; } else { push @buffer, "serial --unit=$sunit --speed=$sspeed\n"; } @@ -1360,7 +1439,7 @@ sub main set_grub2_root_device($imageroot, $grub_config, $root); } fix_grub_dom0mem($imageroot, $grub_config); - fix_console($imageroot, $grub_config); + fix_console($imageroot, $bootloader, $grub_config); fix_swap_partitions($imageroot, $root, $kernel_has_ide ? $old_root : undef ); diff --git a/clientside/tmcc/linux/prepare b/clientside/tmcc/linux/prepare index 4e672e52a..bef6382cd 100755 --- a/clientside/tmcc/linux/prepare +++ b/clientside/tmcc/linux/prepare @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# Copyright (c) 2000-2015 University of Utah and the Flux Group. +# Copyright (c) 2000-2016 University of Utah and the Flux Group. # # {{{EMULAB-LICENSE # @@ -49,6 +49,7 @@ my $VARACCTDIR = "/var/account"; my $VARACCTSDIR = "/var/log/sa"; my $IFTAB = "/etc/iftab"; my $ANACRON = "/usr/sbin/anacron"; +my $GRUBDEF = "/etc/default/grub"; # # Dead wood in $BINDIR @@ -353,6 +354,11 @@ if (-f $driftfile) { close(DRIFT); } +if (-f "$GRUBDEF.preemulab") { + print "Restoring original $GRUBDEF file ...\n"; + system("cp -p $GRUBDEF.preemulab $GRUBDEF"); +} + print "Clearing out $RUNDIR ...\n"; system("rm -rf $RUNDIR/*.pid $RUNDIR/sudo/* $RUNDIR/pump.sock"); -- GitLab