55

I have Ubuntu 10.10 Server installed on a single-board machine in a semi-embedded environment; no keyboard or screen, just SSH access to it.

So it's really frustrating when it occasionally boots up and gets stuck on the GRUB menu, waiting for a keystroke to select the first option.

How do I configure GRUB to under no circumstances wait for a keystroke?

Update #1: There is no menu.lst, since this is GRUB 2. But I do have an /etc/default/grub which is like so:

GRUB_DEFAULT=0
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""

Update #2: I figured it out. On boots which follow unsuccessful boots, GRUB disables its own timeout. Since showing the menu makes a boot unsuccessful, this is an inescapable loop. This behaviour may be disabled by editing the /etc/grub.d/00_header file, and changing the make_timeout function:

make_timeout ()
{
    echo "set timeout=0"
}

Now exit and re-run the grub configuration updater script:

sudo update-grub2

It makes no sense to me that this behaviour would be the default for Ubuntu Server, a product intended for machines accessed by console.

mikepurvis
  • 1,047
  • 2
  • 9
  • 17
  • 1
    What's your `/boot/grub/menu.lst` look like? – Shane Madden Mar 04 '11 at 18:20
  • 8
    You are welcome to post your findings as an answer to your own question, instead of as an edit. That way, we have the opportunity to upvote your answer if we like it. – Skyhawk Mar 04 '11 at 21:39

7 Answers7

41

For Ubuntu 12.04 LTS there is a specific option that can be set in /etc/default/grub.

For example, if you want to have a 2 seconds timeout (thus avoiding hangs for unattended reboots) just add the following line in /etc/default/grub:

GRUB_RECORDFAIL_TIMEOUT=2

Remember to run update-grub after that...

  • This fixed my inital problem, which was the same as the OPs but now I noticed that on the rare occasion when I connect my server to a monitor I don't see anything. The monitor doesn't even get a connection, but SSH still works fine. Is this expected? – Dowlers May 23 '15 at 06:08
18

Here are instructions for Ubuntu 10.10, which are slightly different from prior versions. In file /etc/grub.d/00_header comment out the stupid check for a prior boot failure:

##if [ \${recordfail} = 1 ]; then
##  set timeout=-1
##else
  set timeout=${2}
##fi

Then update:

sudo update-grub

Be aware that if there is a second drive with Linux attached, grub2 will find it, and ask you at boot which one you want. Remove all extra drives before running "update-grub".

See also https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/797544

Bryce
  • 551
  • 5
  • 13
6

I came across this deeply unpleasant design oversight with Ubuntu Server 9.10. Your fix has helped me enormously. I just wanted to point out that the fix needed for 9.10 is different as there is no "make_timeout ()" function in the same file.

For Ubuntu 9.10, go to the end of the same file (00_header) and change the following:

if [ \${recordfail} = 1 ]; then
  set timeout=-1
else
  set timeout=${GRUB_TIMEOUT}
fi
EOF

to

if [ \${recordfail} = 1 ]; then
  set timeout=${GRUB_TIMEOUT}
else
  set timeout=${GRUB_TIMEOUT}
fi
EOF

As before, then run:

sudo update-grub2
GNTC
  • 61
  • 3
  • Brilliant solution, have been wondering how to do this, works perfectly! Note: When you update grub, you only need to run: "sudo update grub" regardless of whatever version of grub you are running. –  Apr 20 '11 at 17:26
  • This has just saved my bacon - my server's been sat at the grub menu on every reboot for a week - had no idea what was wrong and had tried everything. This and the tip in the question did it. Thanks so much. – Darren Greaves Apr 12 '12 at 12:35
1

Configure GRUB for serial access (and your bootloader, while you are at it) and keep an open serial port, null-modem cable, and USB-to-RS232 converter handy for these instances. I run a headless server and a Guruplug and wouldn't have it any other way.

LawrenceC
  • 1,192
  • 6
  • 14
1

I just set a long timeout for recordfail:

if [ "\${recordfail}" = 1 ]; then
  set timeout=30
else
  set timeout=${2}

Meaning you get 30 sec timeout when you boot, if the previous boot failed. (Not unlike how that other OS does it...)

This could (and IMHO should) even be a setting right there in /etc/default/grub.

Gaute Lund
  • 11
  • 1
1

I really don't know why this is the default action, especially for a server, but this is what I have implemented in my server setup scripts.

sudo sed -i 's/set timeout=-1/set timeout=30/g' /etc/grub.d/00_header
sudo update-grub
1

This approach is a bit cleaner - just modify /etc/default/grub to add the line:

GRUB_RECORDFAIL_TIMEOUT=2

...which one might do automatically with something like this in provisioning:

if grep '^GRUB_RECORDFAIL_TIMEOUT=' /etc/default/grub ; then
   echo GOOD: /etc/default/grub
else
   echo FIXING: /etc/default/grub
   perl -pi.bak -e \
      's/^(GRUB_TIMEOUT=.*\n)/${1}GRUB_RECORDFAIL_TIMEOUT=2\n/' \
      /etc/default/grub
   update-grub
fi

This should be viable if the variable GRUB_RECORDFAIL_TIMEOUT is mentioned in /etc/grub.d/00_header (as I'm seeing in 12.04 LTS) in:

make_timeout ()
{
    cat << EOF
if [ "\${recordfail}" = 1 ]; then
  set timeout=${GRUB_RECORDFAIL_TIMEOUT:--1}
else
  set timeout=${2}
fi
EOF
}

I'm a bit curious about whether digging into how the failures are recorded might yield an even better answer.

Alex North-Keys
  • 531
  • 4
  • 6
  • The GRUB_RECORDFAIL_TIMEOUT parameter has been added since this question was originally discussed. Nowadays, yes, this is the better method. – mikepurvis May 13 '13 at 14:58