diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 67fcd10ceb8c..bc19dd8c62fa 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -26,11 +26,11 @@ let inherit (cfg) version extraConfig extraPerEntryConfig extraEntries extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout - default devices; + default devices fsIdentifier; path = (makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils ]) + ":" + (makeSearchPath "sbin" [ - pkgs.mdadm + pkgs.mdadm pkgs.utillinux ]); }); @@ -210,6 +210,21 @@ in ''; }; + fsIdentifier = mkOption { + default = "uuid"; + type = types.addCheck types.string + (type: type == "uuid" || type == "label" || type = "provided"); + description = '' + Determines how grub will identify devices when generating the + configuration file. A value of uuid / label signifies that grub + will always resolve the uuid or label of the device before using + it in the configuration. A value of provided means that grub will + use the device name as show in df or + mount. Note, zfs zpools / datasets are ignored + and will always be mounted using their labels. + ''; + }; + zfsSupport = mkOption { default = false; type = types.bool; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index b9f61337cefd..2615bc3ae11e 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -8,6 +8,7 @@ use File::stat; use File::Copy; use POSIX; use Cwd; +use Switch; my $defaultConfig = $ARGV[1] or die; @@ -40,6 +41,7 @@ my $configurationLimit = int(get("configurationLimit")); my $copyKernels = get("copyKernels") eq "true"; my $timeout = int(get("timeout")); my $defaultEntry = int(get("default")); +my $fsIdentifier = get("fsIdentifier"); $ENV{'PATH'} = get("path"); die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2; @@ -87,13 +89,27 @@ sub GrubFs { $path = "/" . substr($fs->device, $sid) . "/@" . $path; } } else { - my $lbl = "/dev/disk/by-label/"; - if (index($fs->device, $lbl) == 0) { - $search = "--label " . substr($fs->device, length($lbl)); - } - my $uuid = "/dev/disk/by-uuid/"; - if (index($fs->device, $uuid) == 0) { - $search = "--fs-uuid " . substr($fs->device, length($uuid)); + my $idCmd = "\$(blkid -o export $fs->device) 2>/dev/null; echo" + switch ($fsIdentifier) { + case "uuid" { + $search = "--fs-uuid " . `$idCmd \$UUID`; + } + case "label" { + $search = "--label " . `$idCmd \$LABEL`; + } + case "provided" { + my $lbl = "/dev/disk/by-label/"; + if (index($fs->device, $lbl) == 0) { + $search = "--label " . substr($fs->device, length($lbl)); + } + my $uuid = "/dev/disk/by-uuid/"; + if (index($fs->device, $uuid) == 0) { + $search = "--fs-uuid " . substr($fs->device, length($uuid)); + } + } + else { + die "invalid fs identifier type\n"; + } } } if (not $search eq "") {