recordfail timeout always forced on FS without writable envblocks

Bug #1918736 reported by Jasper
28
This bug affects 6 people
Affects Status Importance Assigned to Milestone
grub2 (Ubuntu)
Confirmed
Wishlist
Unassigned

Bug Description

# What is happening
When `GRUB_TIMEOUT=1` is set in `/etc/default/grub` and `update-grub` is run, the desired grub boot menu timeout of 1 second is not acknowledged.
This is on an EFI system.

The following is the relevant snippet of `/boot/grub/grub.cfg`:
```
if [ "${recordfail}" = 1 ] ; then
  set timeout=30
else
  if [ x$feature_timeout_style = xy ] ; then
    set timeout_style=hidden
    set timeout=1
  # Fallback hidden-timeout code in case the timeout_style feature is
  # unavailable.
  elif sleep --interruptible 1 ; then
    set timeout=0
  fi
fi
if [ $grub_platform = efi ]; then
  set timeout=30
  if [ x$feature_timeout_style = xy ] ; then
    set timeout_style=menu
  fi
fi
```

The issue here is that on an EFI system, the `timeout` is overridden by the later test to 30 seconds.

# What is expected
I expect that when I set `GRUB_TIMEOUT=1` in `/etc/default/grub` that the grub menu will timeout (continue to boot) in 1 second.

# Workaround
The EFI timeout is taken from `GRUB_HIDDEN_TIMEOUT_QUIET` in `/etc/grub.d/00_header`. Adding `GRUB_HIDDEN_TIMEOUT_QUIET=1` solves the problem, but is the wrong approach.

# Possible solutions
As a user I do not see why on an EFI system there should be a separate timeout, or indeed that the timeout should even depend on the system type. i.e As a user I don't care.

Looking at the generated grub config I would expect that the generated output would be:
```
if [ "${recordfail}" = 1 ] ; then
  set timeout=30
else
  if [ x$feature_timeout_style = xy ] ; then
    set timeout_style=hidden
    set timeout=1
  # Fallback hidden-timeout code in case the timeout_style feature is
  # unavailable.
  elif sleep --interruptible 1 ; then
    set timeout=0
  fi
fi
if [ $grub_platform = efi ]; then
  set timeout=1
  if [ x$feature_timeout_style = xy ] ; then
    set timeout_style=menu
  fi
fi
```

but am confused as to why the EFI detection is in a separate `if...`

Clearly the code in `/etc/grub.d/00_header` should be changed from:
```
413 if [ \$grub_platform = efi ]; then
414 set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
415 if [ x\$feature_timeout_style = xy ] ; then
416 set timeout_style=menu
417 fi
418 fi
```
to
```
413 if [ \$grub_platform = efi ]; then
414 set timeout=${GRUB_TIMEOUT:-30}
415 if [ x\$feature_timeout_style = xy ] ; then
416 set timeout_style=menu
417 fi
418 fi
```

# Additional information

Ubunutu version:
```
lsb_release -r
Release: 20.10
```

Package version
```
dpkg -l grub2-common
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-================-============-=====================================================
ii grub2-common 2.04-1ubuntu35.4 amd64 GRand Unified Bootloader (common files for version 2)
```

Revision history for this message
Jasper (jasper-mackenzie) wrote :

This is potentially the same as #1814403

Revision history for this message
goniomdq (jose-goni) wrote :

I don't think this is a duplicate of #1814403
And I agree with the OP that the menu timeout in EFI platforms should be controlled by GRUB_TIMEOUT and not by GRUB_RECORDFAIL_TIMEOUT. It doesn't make sense to me that it's GRUB_RECORDFAIL_TIMEOUT.
However, I'd be happy to be schooled here to understand why it needs to be this way.
Cheers.

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in grub2 (Ubuntu):
status: New → Confirmed
Revision history for this message
Nelson Minar (g-nelson) wrote (last edit ):

This bug dates back to 2019. My system boots 8x faster when I fix it.

There's a lot of discussion in various places about the problem, the usual suggested fix is to set GRUB_RECORDFAIL_TIMEOUT in /etc/default/grub to change the delay from 30 seconds. Which isn't a great fix; it's hiding a problem and also it's disrupting the useful behavior on an actually failed boot. I suspect this change was put in place because detecting a failed boot was not working properly in EFI systems. There's a similar problem reported related to LVM boots.

Here's the exact bit of code in /etc/grub/00_config in Ubuntu 22.04.1 that is the problem

if [ \$grub_platform = efi ]; then
  set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}

Some other references:

https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1800722/comments/16
https://askubuntu.com/questions/1120948/grub-recordfail-broken-regarding-lvm
https://forums.linuxmint.com/viewtopic.php?t=287026

*Update* I re-read the code and realized I misunderstood something; this overriding of timeout only happens if GRUB thinks the boot volume is not writable. See the check_writable function for how that works. In my case it's because I'm booting Btrfs.

Revision history for this message
Mate Kukri (mkukri) wrote :

The long timeout only happens when boot fails and GRUB must show the menu for kernel selection.

Otherwise your set timeout is respected.

As per the above command, GRUB drivers cannot write the environment block to certain filesystems and recordfail doesn't work, so the timeout is always shown.

Changed in grub2 (Ubuntu):
importance: Undecided → Wishlist
summary: - update-grub uses the wrong timout for efi system
+ recordfail timeout always forced on FS without writable envblocks
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.