Skip to content

Commit

Permalink
nixos/grub: implements GRUB_SAVEDEFAULT feature
Browse files Browse the repository at this point in the history
Grub will remember the configuration that was booted and
select it as default menu entry the next time (NixOS#108206).
  • Loading branch information
SrTobi committed Jul 28, 2021
1 parent 6e12183 commit eff8d3b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
2 changes: 2 additions & 0 deletions nixos/modules/system/boot/loader/grub/grub.nix
Expand Up @@ -553,6 +553,8 @@ in
apply = toString;
description = ''
Index of the default menu item to be booted.
Can also be set to "saved", which will make GRUB select
the menu item that was used at the last boot.
'';
};

Expand Down
31 changes: 29 additions & 2 deletions nixos/modules/system/boot/loader/grub/install-grub.pl
Expand Up @@ -85,6 +85,7 @@ sub runCommand {
my $forceInstall = get("forceInstall");
my $font = get("font");
my $theme = get("theme");
my $saveDefault = $defaultEntry eq "saved";
$ENV{'PATH'} = get("path");

die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
Expand Down Expand Up @@ -250,6 +251,8 @@ sub GrubFs {
my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n";

if ($grubVersion == 1) {
# $defaultEntry might be "saved", indicating that we want to use the last selected configuration as default.
# Incidentally this is already the correct value for the grub 1 config to achieve this behaviour.
$conf .= "
default $defaultEntry
timeout $timeout
Expand Down Expand Up @@ -305,6 +308,10 @@ sub GrubFs {
" . $grubStore->search;
}
# FIXME: should use grub-mkconfig.
my $defaultEntryText = $defaultEntry;
if ($saveDefault) {
$defaultEntryText = "\"\${saved_entry}\"";
}
$conf .= "
" . $grubBoot->search . "
if [ -s \$prefix/grubenv ]; then
Expand All @@ -318,11 +325,19 @@ sub GrubFs {
set next_entry=
save_env next_entry
set timeout=1
set boot_once=true
else
set default=$defaultEntry
set default=$defaultEntryText
set timeout=$timeout
fi
function savedefault {
if [ -z \"\${boot_once}\"]; then
saved_entry=\"\${chosen}\"
save_env saved_entry
fi
}
# Setup the graphics stack for bios and efi systems
if [ \"\${grub_platform}\" = \"efi\" ]; then
insmod efi_gop
Expand Down Expand Up @@ -468,9 +483,16 @@ sub addEntry {
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
$conf .= " kernel $xen $xenParams\n" if $xen;
$conf .= " " . ($xen ? "module" : "kernel") . " $kernel $kernelParams\n";
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n";
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n";
if ($saveDefault) {
$conf .= " savedefault\n";
}
$conf .= "\n";
} else {
$conf .= "menuentry \"$name\" " . ($options||"") . " {\n";
if ($saveDefault) {
$conf .= " savedefault\n";
}
$conf .= $grubBoot->search . "\n";
if ($copyKernels == 0) {
$conf .= $grubStore->search . "\n";
Expand Down Expand Up @@ -605,6 +627,11 @@ sub getEfiTarget {

# Append entries detected by os-prober
if (get("useOSProber") eq "true") {
if ($saveDefault) {
# os-prober will read this to determine if "savedefault" should be added to generated entries
$ENV{'GRUB_SAVEDEFAULT'} = "true";
}

my $targetpackage = ($efiTarget eq "no") ? $grub : $grubEfi;
system(get("shell"), "-c", "pkgdatadir=$targetpackage/share/grub $targetpackage/etc/grub.d/30_os-prober >> $tmpFile");
}
Expand Down

0 comments on commit eff8d3b

Please sign in to comment.