From 4f832b521729daf54f83d0b5c6ff008d5311a81a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 05:02:09 -0500 Subject: [PATCH 01/38] Revert "grub: Allow setting the boot root explicitly" This reverts commit e4630c1d41d513eb709bddb39043da84442235a7. --- nixos/modules/system/boot/loader/grub/grub.nix | 11 +---------- nixos/modules/system/boot/loader/grub/install-grub.pl | 5 ----- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 0cc060db8f90..a3b09223cbb8 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -25,7 +25,7 @@ let inherit (cfg) version extraConfig extraPerEntryConfig extraEntries extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout - default devices explicitBootRoot; + default devices; path = (makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils ]) + ":" + (makeSearchPath "sbin" [ @@ -209,15 +209,6 @@ in ''; }; - explicitBootRoot = mkOption { - default = ""; - type = types.str; - description = '' - The relative path of /boot within the parent volume. Leave empty - if /boot is not a btrfs subvolume. - ''; - }; - }; }; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index c3aa8518b8bb..a83733db63b0 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -39,7 +39,6 @@ my $configurationLimit = int(get("configurationLimit")); my $copyKernels = get("copyKernels") eq "true"; my $timeout = int(get("timeout")); my $defaultEntry = int(get("default")); -my $explicitBootRoot = get("explicitBootRoot"); $ENV{'PATH'} = get("path"); die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2; @@ -62,10 +61,6 @@ if (stat("/")->dev != stat("/boot")->dev) { $copyKernels = 1; } -if ($explicitBootRoot ne "") { - $bootRoot = $explicitBootRoot; -} - # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; From f2bef62716b4c5853ea16465f31182569dbb80ef Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 21 Oct 2013 05:09:02 -0500 Subject: [PATCH 02/38] Update grub 2.00 to 2.02-beta2 --- pkgs/tools/misc/grub/2.0x.nix | 40 ++++++++++++++++++--------------- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index b1877bdcf98c..59658e47a08f 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -1,11 +1,17 @@ -{ fetchurl, stdenv, flex, bison, gettext, ncurses, libusb, freetype, qemu -, devicemapper, EFIsupport ? false }: +{ fetchurl, stdenv, autogen, flex, bison, python, autoconf, automake +, gettext, ncurses, libusb, freetype, qemu, devicemapper +, linuxPackages ? null +, EFIsupport ? false +, zfsSupport ? false +}: + +assert zfsSupport -> linuxPackages != null && linuxPackages.zfs != null; let prefix = "grub${if EFIsupport then "-efi" else ""}"; - version = "2.00"; + version = "2.02-beta2"; unifont_bdf = fetchurl { url = "http://unifoundry.com/unifont-5.1.20080820.bdf.gz"; @@ -18,13 +24,14 @@ stdenv.mkDerivation rec { name = "${prefix}-${version}"; src = fetchurl { - url = "mirror://gnu/grub/grub-${version}.tar.xz"; - sha256 = "0n64hpmsccvicagvr0c6v0kgp2yw0kgnd3jvsyd26cnwgs7c6kkq"; + url = "http://git.savannah.gnu.org/cgit/grub.git/snapshot/grub-2.02-beta2.tar.gz"; + sha256 = "1n2l7k76lqqaavz12615vx5kca0kl8g13bkimc7xsd9s7c1ir5lr"; }; - nativeBuildInputs = [ flex bison ]; + nativeBuildInputs = [ autogen flex bison python autoconf automake ]; buildInputs = [ ncurses libusb freetype gettext devicemapper ] - ++ stdenv.lib.optional doCheck qemu; + ++ stdenv.lib.optional doCheck qemu + ++ stdenv.lib.optional zfsSupport linuxPackages.zfs; preConfigure = '' for i in "tests/util/"*.in @@ -43,14 +50,11 @@ stdenv.mkDerivation rec { # See . sed -i "tests/util/grub-shell.in" \ -e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g' - - # Fix for building on Glibc 2.16. Won't be needed once the - # gnulib in grub is updated. - sed -i '/gets is a security hole/d' grub-core/gnulib/stdio.in.h ''; prePatch = - '' gunzip < "${unifont_bdf}" > "unifont.bdf" + '' sh autogen.sh + gunzip < "${unifont_bdf}" > "unifont.bdf" sed -i "configure" \ -e "s|/usr/src/unifont.bdf|$PWD/unifont.bdf|g" ''; @@ -61,8 +65,8 @@ stdenv.mkDerivation rec { let arch = if stdenv.system == "i686-linux" then "i386" else if stdenv.system == "x86_64-linux" then "x86_64" else throw "unsupported EFI firmware architecture"; - in - stdenv.lib.optionals EFIsupport + in stdenv.lib.optional zfsSupport "--enable-libzfs" + ++ stdenv.lib.optionals EFIsupport [ "--with-platform=efi" "--target=${arch}" "--program-prefix=" ]; doCheck = false; @@ -72,7 +76,7 @@ stdenv.mkDerivation rec { paxmark pms $out/sbin/grub-{probe,bios-setup} ''; - meta = { + meta = with stdenv.lib; { description = "GNU GRUB, the Grand Unified Boot Loader (2.x beta)"; longDescription = @@ -87,13 +91,13 @@ stdenv.mkDerivation rec { operating system (e.g., GNU). ''; - homepage = http://www.gnu.org/software/grub/; + homepage = http://wwwp.gnu.org/software/grub/; - license = stdenv.lib.licenses.gpl3Plus; + license = licenses.gpl3Plus; platforms = if EFIsupport then [ "i686-linux" "x86_64-linux" ] else - stdenv.lib.platforms.gnu; + platforms.gnu; }; } diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a8540bdb1f61..c5b511df9c02 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1218,7 +1218,7 @@ let buggyBiosCDSupport = config.grub.buggyBiosCDSupport or true; }; - grub2 = callPackage ../tools/misc/grub/2.0x.nix { libusb = libusb1; flex = flex_2_5_35; }; + grub2 = callPackage ../tools/misc/grub/2.0x.nix { }; grub2_efi = grub2.override { EFIsupport = true; }; From 3c6e2fbba910cd3f110a0388c0a374d1573082ef Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 9 Apr 2014 13:27:18 -0500 Subject: [PATCH 03/38] Add optional zfsSupport to the nixos grub configuration --- nixos/modules/system/boot/loader/grub/grub.nix | 14 +++++++++++++- pkgs/top-level/all-packages.nix | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index a3b09223cbb8..25cec57431e1 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -6,7 +6,8 @@ let cfg = config.boot.loader.grub; - realGrub = if cfg.version == 1 then pkgs.grub else pkgs.grub2; + realGrub = if cfg.version == 1 then pkgs.grub + else pkgs.grub2.override { zfsSupport = cfg.zfsSupport }; grub = # Don't include GRUB if we're only generating a GRUB menu (e.g., @@ -209,6 +210,14 @@ in ''; }; + zfsSupport = mkOption { + default = false; + type = types.bool; + description = '' + Whether grub should be build against libzfs. + ''; + }; + }; }; @@ -251,6 +260,9 @@ in ${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}" '') config.boot.loader.grub.extraFiles); + assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2; + message = "Only grub version 2 provides zfs support";}]; + }) ]; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c5b511df9c02..2dc957cb3db3 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1222,6 +1222,8 @@ let grub2_efi = grub2.override { EFIsupport = true; }; + grub2_zfs = grub2.override { zfsSupport = true; }; + gssdp = callPackage ../development/libraries/gssdp { inherit (gnome) libsoup; }; From 02ab48d0eea6e37d3432f6b8ce4c31b85e8d3ffe Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 9 Apr 2014 13:27:45 -0500 Subject: [PATCH 04/38] Enable grub zfsSupport if zfs is built into the initrd --- nixos/modules/system/boot/loader/grub/grub.nix | 2 +- nixos/modules/tasks/filesystems/zfs.nix | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 25cec57431e1..67fcd10ceb8c 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -7,7 +7,7 @@ let cfg = config.boot.loader.grub; realGrub = if cfg.version == 1 then pkgs.grub - else pkgs.grub2.override { zfsSupport = cfg.zfsSupport }; + else pkgs.grub2.override { zfsSupport = cfg.zfsSupport; }; grub = # Don't include GRUB if we're only generating a GRUB menu (e.g., diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index d7deb44c407c..1c4bbc16b499 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -133,7 +133,7 @@ in }; boot.initrd = mkIf inInitrd { - kernelModules = [ "spl" "zfs" ] ; + kernelModules = [ "spl" "zfs" ]; extraUtilsCommands = '' cp -v ${zfsPkg}/sbin/zfs $out/bin @@ -148,6 +148,10 @@ in ''; }; + boot.loader.grub = mkIf inInitrd { + zfsSupport = true; + }; + systemd.services."zpool-import" = { description = "Import zpools"; after = [ "systemd-udev-settle.service" ]; From c5bdb469ce06cd0b36d1dcd4a977f97644776546 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 21 Oct 2013 01:17:23 -0500 Subject: [PATCH 05/38] Update the grub configuration script to handle more complex filesystem layouts including full zfs / and /boot --- .../system/boot/loader/grub/install-grub.pl | 79 +++++++++++++++---- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index a83733db63b0..b9f61337cefd 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -1,5 +1,6 @@ use strict; use warnings; +use Class::Struct; use XML::LibXML; use File::Basename; use File::Path; @@ -47,20 +48,64 @@ print STDERR "updating GRUB $grubVersion menu...\n"; mkpath("/boot/grub", 0, 0700); - # Discover whether /boot is on the same filesystem as / and # /nix/store. If not, then all kernels and initrds must be copied to -# /boot, and all paths in the GRUB config file must be relative to the -# root of the /boot filesystem. `$bootRoot' is the path to be -# prepended to paths under /boot. -my $bootRoot = "/boot"; -if (stat("/")->dev != stat("/boot")->dev) { - $bootRoot = ""; - $copyKernels = 1; -} elsif (stat("/boot")->dev != stat("/nix/store")->dev) { +# /boot. +if (stat("/boot")->dev != stat("/nix")->dev) { $copyKernels = 1; } +# Discover information about the location of /boot +struct(Fs => { + device => '$', + type => '$', + mount => '$', +}); +sub GetFs { + my ($dir) = @_; + my @boot = split(/[ \n\t]+/, `df -T "$dir" | tail -n 1`); + return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]); +} +struct (Grub => { + path => '$', + search => '$', +}); +my $driveid = 1; +sub GrubFs { + my ($dir) = @_; + my $fs = GetFs($dir); + my $path = "/" . substr($dir, length($fs->mount)); + my $search = ""; + if ($grubVersion > 1) { + if ($fs->type eq "zfs") { + my $sid = index($fs->device, "/"); + if ($sid < 0) { + $search = "--label " . $fs->device; + $path = "/@" . $path; + } else { + $search = "--label " . substr($fs->device, 0, $sid); + $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)); + } + } + if (not $search eq "") { + $search = "search --set=drive$driveid " . $search; + $path = "(\$drive$driveid)" . $path; + $driveid += 1; + } + } + return Grub->new(path => $path, search => $search); +} +my $grubBoot = GrubFs("/boot"); +my $grubStore = GrubFs("/nix"); # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; @@ -72,12 +117,14 @@ if ($grubVersion == 1) { "; if ($splashImage) { copy $splashImage, "/boot/background.xpm.gz" or die "cannot copy $splashImage to /boot\n"; - $conf .= "splashimage $bootRoot/background.xpm.gz\n"; + $conf .= "splashimage " . $grubBoot->path . "/background.xpm.gz\n"; } } else { $conf .= " + " . $grubBoot->search . " + " . $grubStore->search . " if [ -s \$prefix/grubenv ]; then load_env fi @@ -98,7 +145,7 @@ else { set timeout=$timeout fi - if loadfont $bootRoot/grub/fonts/unicode.pf2; then + if loadfont " . $grubBoot->path . "/grub/fonts/unicode.pf2; then set gfxmode=640x480 insmod gfxterm insmod vbe @@ -112,7 +159,7 @@ else { copy $splashImage, "/boot/background.png" or die "cannot copy $splashImage to /boot\n"; $conf .= " insmod png - if background_image $bootRoot/background.png; then + if background_image " . $grubBoot->path . "/background.png; then set color_normal=white/black set color_highlight=black/white else @@ -134,7 +181,7 @@ mkpath("/boot/kernels", 0, 0755) if $copyKernels; sub copyToKernelsDir { my ($path) = @_; - return $path unless $copyKernels; + return $grubStore->path . substr($path, length("/nix")) unless $copyKernels; $path =~ /\/nix\/store\/(.*)/ or die; my $name = $1; $name =~ s/\//-/g; my $dst = "/boot/kernels/$name"; @@ -147,7 +194,7 @@ sub copyToKernelsDir { rename $tmp, $dst or die "cannot rename $tmp to $dst\n"; } $copied{$dst} = 1; - return "$bootRoot/kernels/$name"; + return $grubBoot->path . "/kernels/$name"; } sub addEntry { @@ -174,6 +221,8 @@ sub addEntry { $conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n"; } else { $conf .= "menuentry \"$name\" {\n"; + $conf .= $grubBoot->search . "\n"; + $conf .= $grubStore->search . "\n"; $conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig; $conf .= " multiboot $xen $xenParams\n" if $xen; $conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n"; @@ -191,7 +240,7 @@ addEntry("NixOS - Default", $defaultConfig); $conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS; # extraEntries could refer to @bootRoot@, which we have to substitute -$conf =~ s/\@bootRoot\@/$bootRoot/g; +$conf =~ s/\@bootRoot\@/$grubBoot->path/g; # Emit submenus for all system profiles. sub addProfile { From fba9f641a8ed54c27b1d9fadbd2022d8e18ce180 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 29 Apr 2014 22:26:23 -0500 Subject: [PATCH 06/38] grub: Add support for forcing devices to be identified with labels or UUIDs --- .../modules/system/boot/loader/grub/grub.nix | 19 ++++++++++-- .../system/boot/loader/grub/install-grub.pl | 30 ++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) 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 "") { From a6e6c85f06395a92062eb31753a8dd8f3b7e733c Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 29 Apr 2014 22:53:11 -0500 Subject: [PATCH 07/38] grub: Add support for detecting btrfs subvolumes --- nixos/modules/system/boot/loader/grub/grub.nix | 2 +- nixos/modules/system/boot/loader/grub/install-grub.pl | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index bc19dd8c62fa..581b76f8fb21 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -28,7 +28,7 @@ let extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout default devices fsIdentifier; path = (makeSearchPath "bin" [ - pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils + pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs ]) + ":" + (makeSearchPath "sbin" [ pkgs.mdadm pkgs.utillinux ]); diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 2615bc3ae11e..814ae7e05f7c 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -111,6 +111,13 @@ sub GrubFs { die "invalid fs identifier type\n"; } } + if ($fs->type eq "btrfs") { + $subvol = `mount | sed -n 's,^$fs->device on .*subvol=\([^,)]*\).*$,\1,p'` + if ($subvol eq "") { + $subvol = `btrfs subvol get-default $fs->mount | sed -n 's,^.*path \([^ ]*\) .*$,\1,p'` + } + $path = "/$subvol"; + } } if (not $search eq "") { $search = "search --set=drive$driveid " . $search; From 70c11772a69dad8f414366f1bce511282853a80b Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 30 Apr 2014 16:51:34 -0500 Subject: [PATCH 08/38] nixos/grub: Fix some silly perl struct accesses --- nixos/modules/system/boot/loader/grub/install-grub.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 814ae7e05f7c..64151a282f16 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -89,7 +89,7 @@ sub GrubFs { $path = "/" . substr($fs->device, $sid) . "/@" . $path; } } else { - my $idCmd = "\$(blkid -o export $fs->device) 2>/dev/null; echo" + my $idCmd = "\$(blkid -o export " . $fs->device . ") 2>/dev/null; echo" switch ($fsIdentifier) { case "uuid" { $search = "--fs-uuid " . `$idCmd \$UUID`; @@ -112,9 +112,9 @@ sub GrubFs { } } if ($fs->type eq "btrfs") { - $subvol = `mount | sed -n 's,^$fs->device on .*subvol=\([^,)]*\).*$,\1,p'` + $subvol = `mount | sed -n 's,^@{[$fs->device]} on .*subvol=\([^,)]*\).*\$,\1,p'` if ($subvol eq "") { - $subvol = `btrfs subvol get-default $fs->mount | sed -n 's,^.*path \([^ ]*\) .*$,\1,p'` + $subvol = `btrfs subvol get-default @{[$fs->mount]} | sed -n 's,^.*path \([^ ]*\) .*\$,\1,p'` } $path = "/$subvol"; } From 525acb4d4fbfdf1ef18486fba4b2aa673065666a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 30 Apr 2014 17:53:23 -0500 Subject: [PATCH 09/38] nixos/grub: Fix typo --- nixos/modules/system/boot/loader/grub/grub.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 581b76f8fb21..57bf2cefa6f4 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -213,7 +213,7 @@ in fsIdentifier = mkOption { default = "uuid"; type = types.addCheck types.string - (type: type == "uuid" || type == "label" || type = "provided"); + (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 From 1f460e00efb99a1450f5b5806d68ff6633641ad8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 30 Apr 2014 18:04:45 -0500 Subject: [PATCH 10/38] grub: Build grub2 from git instead of using the unpredictable generated tarball --- pkgs/tools/misc/grub/2.0x.nix | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index 59658e47a08f..04971b68a845 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -1,4 +1,4 @@ -{ fetchurl, stdenv, autogen, flex, bison, python, autoconf, automake +{ stdenv, fetchurl, fetchgit, autogen, flex, bison, python, autoconf, automake , gettext, ncurses, libusb, freetype, qemu, devicemapper , linuxPackages ? null , EFIsupport ? false @@ -23,9 +23,10 @@ in stdenv.mkDerivation rec { name = "${prefix}-${version}"; - src = fetchurl { - url = "http://git.savannah.gnu.org/cgit/grub.git/snapshot/grub-2.02-beta2.tar.gz"; - sha256 = "1n2l7k76lqqaavz12615vx5kca0kl8g13bkimc7xsd9s7c1ir5lr"; + src = fetchgit { + url = "git://git.sv.gnu.org/grub.git"; + rev = "refs/tags/grub-2.02-beta2"; + sha256 = "157bknkcxibmvq19pagphlwfxd9xny7002gcanfzhjzcjpfz4scy"; }; nativeBuildInputs = [ autogen flex bison python autoconf automake ]; From 99b4792554859b57b6263a807f9335edceb7a4b0 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 30 Apr 2014 18:45:44 -0500 Subject: [PATCH 11/38] nixos/grub: Refactor perl script to remove the Switch module --- .../system/boot/loader/grub/install-grub.pl | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 64151a282f16..fd298333cc4a 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -8,7 +8,6 @@ use File::stat; use File::Copy; use POSIX; use Cwd; -use Switch; my $defaultConfig = $ARGV[1] or die; @@ -78,9 +77,13 @@ sub GrubFs { my $fs = GetFs($dir); my $path = "/" . substr($dir, length($fs->mount)); my $search = ""; + if ($grubVersion > 1) { + # ZFS is completely separate logic as zpools are always identified by a label + # or custom UUID if ($fs->type eq "zfs") { my $sid = index($fs->device, "/"); + if ($sid < 0) { $search = "--label " . $fs->device; $path = "/@" . $path; @@ -89,32 +92,33 @@ sub GrubFs { $path = "/" . substr($fs->device, $sid) . "/@" . $path; } } else { - my $idCmd = "\$(blkid -o export " . $fs->device . ") 2>/dev/null; echo" - switch ($fsIdentifier) { - case "uuid" { - $search = "--fs-uuid " . `$idCmd \$UUID`; + my $idCmd = "\$(blkid -o export " . $fs->device . ") 2>/dev/null; echo"; + + if ($fsIdentifier eq "uuid") { + $search = "--fs-uuid " . `$idCmd \$UUID`; + } elsif ($fsIdentifier eq "label") { + $search = "--label " . `$idCmd \$LABEL`; + } elsif ($fsIdentifier eq "provided") { + my $lbl = "/dev/disk/by-label/"; + + # If the provided dev is identifying the partition using a label or uuid, + # we should get the label / uuid and do a proper search + if (index($fs->device, $lbl) == 0) { + $search = "--label " . substr($fs->device, length($lbl)); } - 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"; + 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"; } + + # BTRFS is a special case in that we need to fix the referrenced path based on subvolumes if ($fs->type eq "btrfs") { - $subvol = `mount | sed -n 's,^@{[$fs->device]} on .*subvol=\([^,)]*\).*\$,\1,p'` + my $subvol = `mount | sed -n 's,^@{[$fs->device]} on .*subvol=\([^,)]*\).*\$,\1,p'`; if ($subvol eq "") { - $subvol = `btrfs subvol get-default @{[$fs->mount]} | sed -n 's,^.*path \([^ ]*\) .*\$,\1,p'` + $subvol = `btrfs subvol get-default @{[$fs->mount]} | sed -n 's,^.*path \([^ ]*\) .*\$,\1,p'`; } $path = "/$subvol"; } From d4e2040099b33f62971aee2f8530e693115cd680 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 06:04:57 -0500 Subject: [PATCH 12/38] nixos/grub: Refactor install-grub.pl and correct perl syntax --- .../system/boot/loader/grub/install-grub.pl | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index fd298333cc4a..f95e8f75431c 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -81,46 +81,62 @@ sub GrubFs { if ($grubVersion > 1) { # ZFS is completely separate logic as zpools are always identified by a label # or custom UUID - if ($fs->type eq "zfs") { - my $sid = index($fs->device, "/"); + if ($fs->type eq 'zfs') { + my $sid = index($fs->device, '/'); if ($sid < 0) { - $search = "--label " . $fs->device; - $path = "/@" . $path; + $search = '--label ' . $fs->device; + $path = '/@' . $path; } else { - $search = "--label " . substr($fs->device, 0, $sid); - $path = "/" . substr($fs->device, $sid) . "/@" . $path; + $search = '--label ' . substr($fs->device, 0, $sid); + $path = '/' . substr($fs->device, $sid) . '/@' . $path; } } else { - my $idCmd = "\$(blkid -o export " . $fs->device . ") 2>/dev/null; echo"; - - if ($fsIdentifier eq "uuid") { - $search = "--fs-uuid " . `$idCmd \$UUID`; - } elsif ($fsIdentifier eq "label") { - $search = "--label " . `$idCmd \$LABEL`; - } elsif ($fsIdentifier eq "provided") { - my $lbl = "/dev/disk/by-label/"; - + if ($fsIdentifier eq 'provided') { # If the provided dev is identifying the partition using a label or uuid, # we should get the label / uuid and do a proper search + my $lbl = '/dev/disk/by-label/'; if (index($fs->device, $lbl) == 0) { - $search = "--label " . substr($fs->device, length($lbl)); + $search = '--label ' . substr($fs->device, length($lbl)); } - my $uuid = "/dev/disk/by-uuid/"; + + my $uuid = '/dev/disk/by-uuid/'; if (index($fs->device, $uuid) == 0) { - $search = "--fs-uuid " . substr($fs->device, length($uuid)); + $search = '--fs-uuid ' . substr($fs->device, length($uuid)); } } else { - die "invalid fs identifier type\n"; + # Determine the identifying type + my %types = ('uuid' => '--fs-uuid', 'label' => '--label'); + $search = $types{$fsIdentifier} . ' '; + + # Based on the type pull in the identifier from the system + my $devInfo = `blkid -o export @{[$fs->device]}`; + my @matches = $devInfo =~ m/@{[uc $fsIdentifier]}=([^\n]*)/; + if ($#matches != 0) { + die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n" + } + $search .= $matches[0]; } # BTRFS is a special case in that we need to fix the referrenced path based on subvolumes - if ($fs->type eq "btrfs") { - my $subvol = `mount | sed -n 's,^@{[$fs->device]} on .*subvol=\([^,)]*\).*\$,\1,p'`; - if ($subvol eq "") { - $subvol = `btrfs subvol get-default @{[$fs->mount]} | sed -n 's,^.*path \([^ ]*\) .*\$,\1,p'`; + if ($fs->type eq 'btrfs') { + my $subvol = ""; + + my @subvols = `mount` =~ m/@{[$fs->device]} on [^\n]*subvol=([^,)]*)/; + if ($#subvols > 0) { + die "Btrfs device @{[$fs->device]} listed multiple times in mount\n" + } elsif ($#subvols == 0) { + $subvol = $subvols[0]; + } else { + my $btrfsDefault = `btrfs subvol get-default @{[$fs->mount]}`; + my @results = $btrfsDefault =~ m/path ([^ ]*)/; + if ($#results > 0) { + die "Btrfs device @{[$fs->device]} has multiple default subvolumes\n"; + } elsif ($#results == 1) { + $subvol = $results[0]; + } } - $path = "/$subvol"; + $path = "/$subvol" . $path; } } if (not $search eq "") { From 769d2dc6bf7bba3867e13c125fc0a6d5c76aa19a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 19:08:54 -0500 Subject: [PATCH 13/38] nixos/grub: Catch errors from command execution --- .../system/boot/loader/grub/install-grub.pl | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index f95e8f75431c..6748a5ca08fa 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -28,6 +28,14 @@ sub writeFile { close FILE or die; } +sub runCommand { + my ($cmd) = @_; + open FILE, "$cmd 2>/dev/null |" or die "Failed to execute: $cmd\n"; + my @ret = ; + close FILE; + return ($?, @ret); +} + my $grub = get("grub"); my $grubVersion = int(get("version")); my $extraConfig = get("extraConfig"); @@ -64,7 +72,11 @@ struct(Fs => { }); sub GetFs { my ($dir) = @_; - my @boot = split(/[ \n\t]+/, `df -T "$dir" | tail -n 1`); + my ($status, @dfOut) = runCommand("df -T $dir"); + if ($status != 0 || $#dfOut != 1) { + die "Failed to retrieve output about $dir from `df`"; + } + my @boot = split(/[ \n\t]+/, $dfOut[1]); return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]); } struct (Grub => { @@ -110,8 +122,11 @@ sub GrubFs { $search = $types{$fsIdentifier} . ' '; # Based on the type pull in the identifier from the system - my $devInfo = `blkid -o export @{[$fs->device]}`; - my @matches = $devInfo =~ m/@{[uc $fsIdentifier]}=([^\n]*)/; + my ($status, @devInfo) = runCommand("blkid -o export @{[$fs->device]}"); + if ($status != 0) { + die "Failed to get blkid info for @{[$fs->device]}"; + } + my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/; if ($#matches != 0) { die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n" } @@ -122,14 +137,21 @@ sub GrubFs { if ($fs->type eq 'btrfs') { my $subvol = ""; - my @subvols = `mount` =~ m/@{[$fs->device]} on [^\n]*subvol=([^,)]*)/; + my ($status, @mounts) = runCommand('mount'); + if ($status != 0) { + die "Failed to retreive mount info"; + } + my @subvols = join("", @mounts) =~ m/@{[$fs->device]} on [^\n]*subvol=([^,)]*)/; if ($#subvols > 0) { die "Btrfs device @{[$fs->device]} listed multiple times in mount\n" } elsif ($#subvols == 0) { $subvol = $subvols[0]; } else { - my $btrfsDefault = `btrfs subvol get-default @{[$fs->mount]}`; - my @results = $btrfsDefault =~ m/path ([^ ]*)/; + my ($status, @btrfsOut) = runCommand("btrfs subvol get-default @{[$fs->mount]}"); + if ($status != 0) { + die "Failed to retrieve btrfs default subvolume" + } + my @results = join("", @btrfsOut) =~ m/path ([^ ]*)/; if ($#results > 0) { die "Btrfs device @{[$fs->device]} has multiple default subvolumes\n"; } elsif ($#results == 1) { From 5870ae613f42c99456dcbbc4df01abdce3c1f448 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 20:21:02 -0500 Subject: [PATCH 14/38] nixos/release: Dynamically generate installer tests --- nixos/release.nix | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nixos/release.nix b/nixos/release.nix index 0620b46d46ad..e5a4e7337ab0 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -222,12 +222,11 @@ in rec { tests.firefox = callTest tests/firefox.nix {}; tests.firewall = callTest tests/firewall.nix {}; tests.gnome3 = callTest tests/gnome3.nix {}; - tests.installer.efi = forAllSystems (system: (import tests/installer.nix { inherit system; }).efi.test); - tests.installer.grub1 = forAllSystems (system: (import tests/installer.nix { inherit system; }).grub1.test); - tests.installer.lvm = forAllSystems (system: (import tests/installer.nix { inherit system; }).lvm.test); - tests.installer.rebuildCD = forAllSystems (system: (import tests/installer.nix { inherit system; }).rebuildCD.test); - tests.installer.separateBoot = forAllSystems (system: (import tests/installer.nix { inherit system; }).separateBoot.test); - tests.installer.simple = forAllSystems (system: (import tests/installer.nix { inherit system; }).simple.test); + tests.installer = with pkgs.lib; + let installer = import tests/installer.nix; in + flip mapAttrs (installer { }) (name: _: + forAllSystems (system: (installer { system = system; }).${name}.test) + ); tests.influxdb = callTest tests/influxdb.nix {}; tests.ipv6 = callTest tests/ipv6.nix {}; tests.jenkins = callTest tests/jenkins.nix {}; From 8329d12b799b98a2b220e34ed347417c2d5b8fbe Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 23:11:18 -0500 Subject: [PATCH 15/38] grub: Change fsIdentifier to str from string --- nixos/modules/system/boot/loader/grub/grub.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 57bf2cefa6f4..8ba7ae2c7fa2 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -212,7 +212,7 @@ in fsIdentifier = mkOption { default = "uuid"; - type = types.addCheck types.string + type = types.addCheck types.str (type: type == "uuid" || type == "label" || type == "provided"); description = '' Determines how grub will identify devices when generating the From 809caa87ab88fae9164347c3f1a63f6117c09821 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 06:21:30 -0500 Subject: [PATCH 16/38] tests/installer: Add btrfs tests for grub and nixos-generate-config --- nixos/tests/installer.nix | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 621afffbfc1f..89abafcab83a 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -394,4 +394,49 @@ in { $machine->shutdown; ''; }; + + # Simple btrfs grub testing + btrfsSimple = makeInstallerTest { + createPartitions = '' + $machine->succeed( + "sgdisk -Z /dev/vda", + "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", + "mkfs.btrfs -L root /dev/vda2", + "mount LABEL=root /mnt", + ); + ''; + }; + + # Test to see if we can detect /boot and /nix on subvolumes + btrfsSubvols = makeInstallerTest { + createPartitions = '' + $machine->succeed( + "sgdisk -Z /dev/vda", + "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", + "mkfs.btrfs -L root /dev/vda2", + "btrfs device scan", + "mount LABEL=root /mnt", + "btrfs subvol create /mnt/boot", + "btrfs subvol create /mnt/nixos", + "umount /mnt", + "mount -o defaults,subvol=mnt LABEL=root /mnt", + "mkdir /mnt/boot", + "mount -o defaults,subvol=boot LABEL=root /mnt/boot", + ); + ''; + }; + + # Test to see if we can detect subvols by their id's + btrfsSubvolId = makeInstallerTest { + createPartitions = '' + $machine->succeed("false"); + ''; + }; + + # Test to see if we can detect a default subvolume on / + btrfsDefaultSubvol = makeInstallerTest { + createPartitions = '' + $machine->succeed("false"); + ''; + }; } From 2b703f82d5f257b91389267f11e7914d8df550bf Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 23:11:49 -0500 Subject: [PATCH 17/38] tests/installer: Test for more grub configurations --- nixos/tests/installer.nix | 42 +++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 89abafcab83a..2bee2f77999f 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -35,8 +35,8 @@ let # The configuration to install. - makeConfig = { testChannel, useEFI, grubVersion, grubDevice }: pkgs.writeText "configuration.nix" - '' + makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }: + pkgs.writeText "configuration.nix" '' { config, pkgs, modulesPath, ... }: { imports = @@ -54,6 +54,7 @@ let ''} boot.loader.grub.device = "${grubDevice}"; boot.loader.grub.extraConfig = "serial; terminal_output.serial"; + boot.loader.grub.fsIdentifier = "${grubIdentifier}"; ''} environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ]; @@ -93,7 +94,7 @@ let # disk, and then reboot from the hard disk. It's parameterized with # a test script fragment `createPartitions', which must create # partitions and filesystems. - testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice }: + testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }: let # FIXME: OVMF doesn't boot from virtio http://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg01501.html iface = if useEFI || grubVersion == 1 then "scsi" else "virtio"; @@ -161,7 +162,7 @@ let $machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2"); $machine->copyFileFromHost( - "${ makeConfig { inherit testChannel useEFI grubVersion grubDevice; } }", + "${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; } }", "/mnt/etc/nixos/configuration.nix"); # Perform the installation. @@ -216,13 +217,13 @@ let makeInstallerTest = name: - { createPartitions, testChannel ? false, useEFI ? false, grubVersion ? 2, grubDevice ? "/dev/vda" }: + { createPartitions, testChannel ? false, useEFI ? false, grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid" }: makeTest { inherit iso; name = "installer-" + name; nodes = if testChannel then { inherit webserver; } else { }; testScript = testScriptFun { - inherit createPartitions testChannel useEFI grubVersion grubDevice; + inherit createPartitions testChannel useEFI grubVersion grubDevice grubIdentifier; }; }; @@ -395,6 +396,35 @@ in { ''; }; + # Test using labels to identify volumes in grub + simpleLabels = makeInstallerTest { + createPartitions = '' + $machine->succeed( + "sgdisk -Z /dev/vda", + "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", + "mkfs.ext4 -L root /dev/vda2", + "mount LABEL=root /mnt", + ); + ''; + grubIdentifier = "label"; + }; + + # Test using the provided disk name within grub + simpleProvided = makeInstallerTest { + createPartitions = '' + $machine->succeed( + "sgdisk -Z /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8300 -t 3:8300 -c 2:boot -c 3:root /dev/vda", + "mkfs.ext4 -L boot /dev/vda2", + "mkfs.ext4 -L root /dev/vda3", + "mount LABEL=root /mnt", + "mkdir /mnt/boot", + "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/$UUID /mnt/boot" + ); + ''; + grubIdentifier = "provided"; + }; + # Simple btrfs grub testing btrfsSimple = makeInstallerTest { createPartitions = '' From 62fedf6081200e38df515204683df472e0fe959d Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 23:22:21 -0500 Subject: [PATCH 18/38] installer/btrfs: Typo in subvol --- nixos/tests/installer.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 2bee2f77999f..2064675ecd94 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -449,7 +449,7 @@ in { "btrfs subvol create /mnt/boot", "btrfs subvol create /mnt/nixos", "umount /mnt", - "mount -o defaults,subvol=mnt LABEL=root /mnt", + "mount -o defaults,subvol=nixos LABEL=root /mnt", "mkdir /mnt/boot", "mount -o defaults,subvol=boot LABEL=root /mnt/boot", ); From d4a9645ef0d365e4ff30d2ae29ec163a53869625 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 23:40:51 -0500 Subject: [PATCH 19/38] nixos/grub: Needs mount so add utillinux to bin --- nixos/modules/system/boot/loader/grub/grub.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 8ba7ae2c7fa2..bc9a155ac95b 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -29,6 +29,7 @@ let default devices fsIdentifier; path = (makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs + pkgs.utillinux ]) + ":" + (makeSearchPath "sbin" [ pkgs.mdadm pkgs.utillinux ]); From 8b36bf5c59ef7d2af849a0304f76a6a25b997408 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 1 May 2014 23:52:06 -0500 Subject: [PATCH 20/38] tests/installer: fix mount --- nixos/tests/installer.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 2064675ecd94..a7f7c766157e 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -419,7 +419,7 @@ in { "mkfs.ext4 -L root /dev/vda3", "mount LABEL=root /mnt", "mkdir /mnt/boot", - "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/$UUID /mnt/boot" + "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/\\$UUID /mnt/boot" ); ''; grubIdentifier = "provided"; From 8ff4b3b78048231a9e56d1597ee09592dd05eab8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 00:01:32 -0500 Subject: [PATCH 21/38] tests/installer: Add swap to the new tests --- nixos/tests/installer.nix | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index a7f7c766157e..93b6182a09cf 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -401,7 +401,9 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", "mkfs.ext4 -L root /dev/vda2", "mount LABEL=root /mnt", ); @@ -414,9 +416,11 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8300 -t 3:8300 -c 2:boot -c 3:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+100M -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", + "mkswap /dev/vda3 -L swap", + "swapon -L swap", "mkfs.ext4 -L boot /dev/vda2", - "mkfs.ext4 -L root /dev/vda3", + "mkfs.ext4 -L root /dev/vda4", "mount LABEL=root /mnt", "mkdir /mnt/boot", "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/\\$UUID /mnt/boot" @@ -430,8 +434,10 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", - "mkfs.btrfs -L root /dev/vda2", + "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.btrfs -L root /dev/vda3", "mount LABEL=root /mnt", ); ''; @@ -442,8 +448,10 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -N 2 -t 1:ef02 -t 2:8300 -c 2:root /dev/vda", - "mkfs.btrfs -L root /dev/vda2", + "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.btrfs -L root /dev/vda3", "btrfs device scan", "mount LABEL=root /mnt", "btrfs subvol create /mnt/boot", From 429f785135ebca304767ecf435b5d5e979c2f3f2 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 00:25:38 -0500 Subject: [PATCH 22/38] tests/installer: Fix simple tests --- nixos/tests/installer.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 93b6182a09cf..4fceb19f2342 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -404,7 +404,7 @@ in { "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", "mkswap /dev/vda2 -L swap", "swapon -L swap", - "mkfs.ext4 -L root /dev/vda2", + "mkfs.ext4 -L root /dev/vda3", "mount LABEL=root /mnt", ); ''; @@ -423,7 +423,7 @@ in { "mkfs.ext4 -L root /dev/vda4", "mount LABEL=root /mnt", "mkdir /mnt/boot", - "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/\\$UUID /mnt/boot" + "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/\$UUID /mnt/boot" ); ''; grubIdentifier = "provided"; From 87d5e457fe124facb261d13f52e14a7c6e6511af Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 00:44:36 -0500 Subject: [PATCH 23/38] nixos/grub: Grub detection is much simpler using subvol show --- .../system/boot/loader/grub/install-grub.pl | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 6748a5ca08fa..82809edd6e86 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -135,35 +135,21 @@ sub GrubFs { # BTRFS is a special case in that we need to fix the referrenced path based on subvolumes if ($fs->type eq 'btrfs') { - my $subvol = ""; - - my ($status, @mounts) = runCommand('mount'); + my ($status, @info) = runCommand("btrfs subvol show @{[$fs->device]}"); if ($status != 0) { - die "Failed to retreive mount info"; + die "Failed to retreive subvolume info for @{[$fs->device]}"; } - my @subvols = join("", @mounts) =~ m/@{[$fs->device]} on [^\n]*subvol=([^,)]*)/; + my @subvols = join("", @info) =~ m/Name:[ \t\n]([^ \t\n]*)/; if ($#subvols > 0) { - die "Btrfs device @{[$fs->device]} listed multiple times in mount\n" + die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n" } elsif ($#subvols == 0) { - $subvol = $subvols[0]; - } else { - my ($status, @btrfsOut) = runCommand("btrfs subvol get-default @{[$fs->mount]}"); - if ($status != 0) { - die "Failed to retrieve btrfs default subvolume" - } - my @results = join("", @btrfsOut) =~ m/path ([^ ]*)/; - if ($#results > 0) { - die "Btrfs device @{[$fs->device]} has multiple default subvolumes\n"; - } elsif ($#results == 1) { - $subvol = $results[0]; - } - } - $path = "/$subvol" . $path; + $path = "/$subvols[0]$path"; + } } } if (not $search eq "") { $search = "search --set=drive$driveid " . $search; - $path = "(\$drive$driveid)" . $path; + $path = "(\$drive$driveid)$path"; $driveid += 1; } } From 3bf22679b30bc6f92b7df2a72cdba0403be3be86 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 00:45:06 -0500 Subject: [PATCH 24/38] nixos/grub: Kernels don't need to be copied if we can read the nix store --- nixos/modules/system/boot/loader/grub/install-grub.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 82809edd6e86..d0d5307a804e 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -158,6 +158,11 @@ sub GrubFs { my $grubBoot = GrubFs("/boot"); my $grubStore = GrubFs("/nix"); +# We don't need to copy if we can read the kernels directly +if ($grubStore->search ne "") { + $copyKernels = 0; +} + # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; From 7264941a465b3312c35f2dde6184447c746d9d17 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 00:51:26 -0500 Subject: [PATCH 25/38] tests/installer: Remove unneeded tests --- nixos/tests/installer.nix | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 4fceb19f2342..6f20f6614ebf 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -463,18 +463,4 @@ in { ); ''; }; - - # Test to see if we can detect subvols by their id's - btrfsSubvolId = makeInstallerTest { - createPartitions = '' - $machine->succeed("false"); - ''; - }; - - # Test to see if we can detect a default subvolume on / - btrfsDefaultSubvol = makeInstallerTest { - createPartitions = '' - $machine->succeed("false"); - ''; - }; } From b651097d193089d14e9407a67b95397bf02129e5 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 01:05:10 -0500 Subject: [PATCH 26/38] tests/installer: Swapspace should be larger --- nixos/tests/installer.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 6f20f6614ebf..cb9cc1200626 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -401,7 +401,7 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", "mkswap /dev/vda2 -L swap", "swapon -L swap", "mkfs.ext4 -L root /dev/vda3", @@ -416,7 +416,7 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+100M -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+1G -n 3:0:+100M -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", "mkswap /dev/vda3 -L swap", "swapon -L swap", "mkfs.ext4 -L boot /dev/vda2", @@ -434,7 +434,7 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", "mkswap /dev/vda2 -L swap", "swapon -L swap", "mkfs.btrfs -L root /dev/vda3", @@ -448,7 +448,7 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+100M -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda", "mkswap /dev/vda2 -L swap", "swapon -L swap", "mkfs.btrfs -L root /dev/vda3", From 6549bcff9607efd68ecd8fca8ca15c4446b16fb9 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 01:07:12 -0500 Subject: [PATCH 27/38] tests/installer: Fix provided test uuid and label mounts --- nixos/tests/installer.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index cb9cc1200626..d15c43d29bbe 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -421,9 +421,9 @@ in { "swapon -L swap", "mkfs.ext4 -L boot /dev/vda2", "mkfs.ext4 -L root /dev/vda4", - "mount LABEL=root /mnt", + "mount /dev/disk/by-label/root /mnt", "mkdir /mnt/boot", - "$(blkid -o export /dev/vda2); mount /dev/disk/by-uuid/\$UUID /mnt/boot" + "mount /dev/disk/by-uuid/\$(blkid -s UUID -o value /dev/vda2) /mnt/boot" ); ''; grubIdentifier = "provided"; From c02bc3a9de319195597a16173e04357023e97643 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 01:46:07 -0500 Subject: [PATCH 28/38] nixos/grub: Fix regex for getting subvolume name in btrfs --- nixos/modules/system/boot/loader/grub/install-grub.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index d0d5307a804e..2725cea59960 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -139,7 +139,7 @@ sub GrubFs { if ($status != 0) { die "Failed to retreive subvolume info for @{[$fs->device]}"; } - my @subvols = join("", @info) =~ m/Name:[ \t\n]([^ \t\n]*)/; + my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/; if ($#subvols > 0) { die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n" } elsif ($#subvols == 0) { From 4f096c044f987f036af3fc1888090e6567aaf7b1 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 02:53:32 -0500 Subject: [PATCH 29/38] nixos/grub: Simplify detection of labels / uuids for provided device names --- .../system/boot/loader/grub/install-grub.pl | 22 +++++++++---------- nixos/tests/installer.nix | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 2725cea59960..3c84fccac34c 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -104,28 +104,26 @@ sub GrubFs { $path = '/' . substr($fs->device, $sid) . '/@' . $path; } } else { + my %types = ('uuid' => '--fs-uuid', 'label' => '--label'); + if ($fsIdentifier eq 'provided') { # If the provided dev is identifying the partition using a label or uuid, # we should get the label / uuid and do a proper search - 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 @matches = $fs->device =~ m/\/dev\/disk\/by-(label|uuid)\/(.*)/; + if ($#matches > 1) { + die "Too many matched devices" + } elsif ($#matches == 1) { + $search = "$types{$matches[0]} $matches[1]" } } else { # Determine the identifying type - my %types = ('uuid' => '--fs-uuid', 'label' => '--label'); $search = $types{$fsIdentifier} . ' '; # Based on the type pull in the identifier from the system my ($status, @devInfo) = runCommand("blkid -o export @{[$fs->device]}"); - if ($status != 0) { - die "Failed to get blkid info for @{[$fs->device]}"; - } + if ($status != 0) { + die "Failed to get blkid info for @{[$fs->device]}"; + } my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/; if ($#matches != 0) { die "Couldn't find a $types{$fsIdentifier} for @{[$fs->device]}\n" diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index d15c43d29bbe..0eb67eaa813e 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -416,7 +416,7 @@ in { createPartitions = '' $machine->succeed( "sgdisk -Z /dev/vda", - "sgdisk -n 1:0:+1M -n 2:0:+1G -n 3:0:+100M -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", + "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+1G -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", "mkswap /dev/vda3 -L swap", "swapon -L swap", "mkfs.ext4 -L boot /dev/vda2", From cc62623b37c4ac6e17968b36d9ced8bbf28fb883 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 02:03:25 -0500 Subject: [PATCH 30/38] tests/installer: Provided test should add symlinks to /dev/disk if udev doesn't --- nixos/tests/installer.nix | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 0eb67eaa813e..ef11fcb10019 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -412,8 +412,10 @@ in { }; # Test using the provided disk name within grub + # TODO: Fix udev so the symlinks are unneeded in /dev/disks simpleProvided = makeInstallerTest { createPartitions = '' + my $UUID = "\$(blkid -s UUID -o value /dev/vda2)"; $machine->succeed( "sgdisk -Z /dev/vda", "sgdisk -n 1:0:+1M -n 2:0:+100M -n 3:0:+1G -N 4 -t 1:ef02 -t 2:8300 -t 3:8200 -t 4:8300 -c 2:boot -c 4:root /dev/vda", @@ -421,9 +423,13 @@ in { "swapon -L swap", "mkfs.ext4 -L boot /dev/vda2", "mkfs.ext4 -L root /dev/vda4", + ); + $machine->execute("ln -s ../../vda2 /dev/disk/by-uuid/$UUID"); + $machine->execute("ln -s ../../vda4 /dev/disk/by-label/root"); + $machine->succeed( "mount /dev/disk/by-label/root /mnt", "mkdir /mnt/boot", - "mount /dev/disk/by-uuid/\$(blkid -s UUID -o value /dev/vda2) /mnt/boot" + "mount /dev/disk/by-uuid/$UUID /mnt/boot" ); ''; grubIdentifier = "provided"; From 0f6079d999e3922782f3ce6daf742f32568118ac Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 03:37:50 -0500 Subject: [PATCH 31/38] nixos/grub: Fix spacing and correct subvolume detection --- .../system/boot/loader/grub/install-grub.pl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 3c84fccac34c..acfb85f3bc5c 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -72,10 +72,10 @@ struct(Fs => { }); sub GetFs { my ($dir) = @_; - my ($status, @dfOut) = runCommand("df -T $dir"); - if ($status != 0 || $#dfOut != 1) { - die "Failed to retrieve output about $dir from `df`"; - } + my ($status, @dfOut) = runCommand("df -T $dir"); + if ($status != 0 || $#dfOut != 1) { + die "Failed to retrieve output about $dir from `df`"; + } my @boot = split(/[ \n\t]+/, $dfOut[1]); return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]); } @@ -133,16 +133,16 @@ sub GrubFs { # BTRFS is a special case in that we need to fix the referrenced path based on subvolumes if ($fs->type eq 'btrfs') { - my ($status, @info) = runCommand("btrfs subvol show @{[$fs->device]}"); + my ($status, @info) = runCommand("btrfs subvol show @{[$fs->mount]}"); if ($status != 0) { - die "Failed to retreive subvolume info for @{[$fs->device]}"; + die "Failed to retreive subvolume info for @{[$fs->mount]}"; } my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/; if ($#subvols > 0) { die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n" } elsif ($#subvols == 0) { - $path = "/$subvols[0]$path"; - } + $path = "/$subvols[0]$path"; + } } } if (not $search eq "") { From 940c57e4e86f14cbc25bd63949ef27cc96856425 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 03:44:07 -0500 Subject: [PATCH 32/38] nixos/ova: Grub uuid detection is broken when generating the ova --- nixos/modules/installer/virtualbox-demo.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nixos/modules/installer/virtualbox-demo.nix b/nixos/modules/installer/virtualbox-demo.nix index f68f8dc40aa8..49ec08996104 100644 --- a/nixos/modules/installer/virtualbox-demo.nix +++ b/nixos/modules/installer/virtualbox-demo.nix @@ -10,6 +10,9 @@ with lib; ../profiles/clone-config.nix ]; + # FIXME: UUID detection is currently broken + boot.loader.grub.fsIdentifier = "provided"; + # Allow mounting of shared folders. users.extraUsers.demo.extraGroups = [ "vboxsf" ]; From 2ea1433b77755b954df979307525fa6578f241b8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 2 May 2014 09:17:54 -0500 Subject: [PATCH 33/38] grub: Fetch from alpha.gnu.org instead of git --- pkgs/tools/misc/grub/2.0x.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index 04971b68a845..2c150f8ec96f 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, fetchgit, autogen, flex, bison, python, autoconf, automake +{ stdenv, fetchurl, autogen, flex, bison, python, autoconf, automake , gettext, ncurses, libusb, freetype, qemu, devicemapper , linuxPackages ? null , EFIsupport ? false @@ -23,10 +23,10 @@ in stdenv.mkDerivation rec { name = "${prefix}-${version}"; - src = fetchgit { - url = "git://git.sv.gnu.org/grub.git"; - rev = "refs/tags/grub-2.02-beta2"; - sha256 = "157bknkcxibmvq19pagphlwfxd9xny7002gcanfzhjzcjpfz4scy"; + src = fetchurl { + name = "grub-2.02-beta2.tar.xz"; + url = "http://alpha.gnu.org/gnu/grub/grub-2.02~beta2.tar.xz"; + sha256 = "13a13fhc0wf473dn73zhga15mjvkg6vqp4h25dxg4n7am2r05izn"; }; nativeBuildInputs = [ autogen flex bison python autoconf automake ]; From dd18e67cfb27515791620a0e69e4e427b77e2670 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Sat, 3 May 2014 19:59:47 -0500 Subject: [PATCH 34/38] grub: Cleanup efi support --- pkgs/tools/misc/grub/2.0x.nix | 37 ++++++++++++++++----------------- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index 2c150f8ec96f..028ec5657529 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -1,15 +1,20 @@ { stdenv, fetchurl, autogen, flex, bison, python, autoconf, automake , gettext, ncurses, libusb, freetype, qemu, devicemapper , linuxPackages ? null -, EFIsupport ? false +, efiSupport ? false , zfsSupport ? false }: -assert zfsSupport -> linuxPackages != null && linuxPackages.zfs != null; - +with stdenv.lib; let + efiSystems = { + "i686-linux".target = "i386"; + "x86_64-linux".target = "x86_64"; + }; - prefix = "grub${if EFIsupport then "-efi" else ""}"; + canEfi = any (system: stdenv.system == system) (mapAttrsToList (name: _: name) efiSystems); + + prefix = "grub${if efiSupport then "-efi" else ""}"; version = "2.02-beta2"; @@ -17,8 +22,10 @@ let url = "http://unifoundry.com/unifont-5.1.20080820.bdf.gz"; sha256 = "0s0qfff6n6282q28nwwblp5x295zd6n71kl43xj40vgvdqxv0fxx"; }; +in ( -in +assert efiSupport -> canEfi; +assert zfsSupport -> linuxPackages != null && linuxPackages.zfs != null; stdenv.mkDerivation rec { name = "${prefix}-${version}"; @@ -31,8 +38,8 @@ stdenv.mkDerivation rec { nativeBuildInputs = [ autogen flex bison python autoconf automake ]; buildInputs = [ ncurses libusb freetype gettext devicemapper ] - ++ stdenv.lib.optional doCheck qemu - ++ stdenv.lib.optional zfsSupport linuxPackages.zfs; + ++ optional doCheck qemu + ++ optional zfsSupport linuxPackages.zfs; preConfigure = '' for i in "tests/util/"*.in @@ -62,13 +69,8 @@ stdenv.mkDerivation rec { patches = [ ./fix-bash-completion.patch ]; - configureFlags = - let arch = if stdenv.system == "i686-linux" then "i386" - else if stdenv.system == "x86_64-linux" then "x86_64" - else throw "unsupported EFI firmware architecture"; - in stdenv.lib.optional zfsSupport "--enable-libzfs" - ++ stdenv.lib.optionals EFIsupport - [ "--with-platform=efi" "--target=${arch}" "--program-prefix=" ]; + configureFlags = optional zfsSupport "--enable-libzfs" + ++ optionals efiSupport [ "--with-platform=efi" "--target=${efiSystems.${stdenv.system}.target}" "--program-prefix=" ]; doCheck = false; enableParallelBuilding = true; @@ -96,9 +98,6 @@ stdenv.mkDerivation rec { license = licenses.gpl3Plus; - platforms = if EFIsupport then - [ "i686-linux" "x86_64-linux" ] - else - platforms.gnu; + platforms = platforms.gnu; }; -} +}) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2dc957cb3db3..3d2350b661e5 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1220,7 +1220,7 @@ let grub2 = callPackage ../tools/misc/grub/2.0x.nix { }; - grub2_efi = grub2.override { EFIsupport = true; }; + grub2_efi = grub2.override { efiSupport = true; }; grub2_zfs = grub2.override { zfsSupport = true; }; From babcd70c36d0c2e2cb000eb3085aa7a42104a4ba Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 18 Jun 2014 16:21:57 -0500 Subject: [PATCH 35/38] nixos/release-combined: Add required installer tests --- nixos/release-combined.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index dae3b9210a86..23348e1d089e 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -52,6 +52,10 @@ in rec { (all nixos.tests.installer.lvm) (all nixos.tests.installer.separateBoot) (all nixos.tests.installer.simple) + (all nixos.tests.installer.simpleLabels) + (all nixos.tests.installer.simpleProvided) + (all nixos.tests.installer.btrfsSimple) + (all nixos.tests.installer.btrfsSubvols) (all nixos.tests.ipv6) (all nixos.tests.kde4) (all nixos.tests.login) From 36a47733a264dbfe0d8cb62a1a0d5d4d4b07b715 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 18 Jun 2014 18:43:00 -0500 Subject: [PATCH 36/38] nixos-generate-config: Detect btrfs subvolumes --- .../installer/tools/nixos-generate-config.pl | 21 +++++++++++++++++++ nixos/modules/installer/tools/tools.nix | 1 + 2 files changed, 22 insertions(+) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 66a8152a3a6c..cabdb09ec9c1 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -20,6 +20,13 @@ sub uniq { return @res; } +sub runCommand { + my ($cmd) = @_; + open FILE, "$cmd 2>/dev/null |" or die "Failed to execute: $cmd\n"; + my @ret = ; + close FILE; + return ($?, @ret); +} # Process the command line. my $outDir = "/etc/nixos"; @@ -337,6 +344,20 @@ EOF } } + # Is this a btrfs filesystem? + if ($fsType eq "btrfs") { + my ($status, @info) = runCommand("btrfs subvol show $rootDir$mountPoint"); + if ($status != 0) { + die "Failed to retreive subvolume info for $mountPoint"; + } + my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/; + if ($#subvols > 0) { + die "Btrfs subvol name for $mountPoint listed multiple times in mount\n" + } elsif ($#subvols == 0) { + push @extraOptions, "subvol=$subvols[0]"; + } + } + # Emit the filesystem. $fileSystems .= < Date: Sun, 13 Jul 2014 09:50:45 -0500 Subject: [PATCH 37/38] nixos/install-grub: Check /boot against /nix/store instead of /nix --- nixos/modules/system/boot/loader/grub/install-grub.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index acfb85f3bc5c..d8ee8b500970 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -60,7 +60,7 @@ mkpath("/boot/grub", 0, 0700); # Discover whether /boot is on the same filesystem as / and # /nix/store. If not, then all kernels and initrds must be copied to # /boot. -if (stat("/boot")->dev != stat("/nix")->dev) { +if (stat("/boot")->dev != stat("/nix/store")->dev) { $copyKernels = 1; } From 0fdbc444113a80c1bd0477676a33ab1fb27bae1a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 28 Aug 2014 13:36:41 -0700 Subject: [PATCH 38/38] grub: Fix typo --- pkgs/tools/misc/grub/2.0x.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index 028ec5657529..e3c07af759c9 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -94,7 +94,7 @@ stdenv.mkDerivation rec { operating system (e.g., GNU). ''; - homepage = http://wwwp.gnu.org/software/grub/; + homepage = http://www.gnu.org/software/grub/; license = licenses.gpl3Plus;