summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorThomas Tuegel <ttuegel@gmail.com>2014-09-05 20:01:08 -0500
committerThomas Tuegel <ttuegel@gmail.com>2014-09-05 20:01:08 -0500
commit53fa51717658830f466b539a21d5401056b8adce (patch)
tree6f3f49b764bcc9b9417d88bacf7db5f8285c5113 /nixos
parentf4ebb3ebac9ccaf1dacebba0550c21818101be3d (diff)
parent6fb6ba48f85f7ec8f954428468e96ce55f5535a3 (diff)
downloadnixlib-53fa51717658830f466b539a21d5401056b8adce.tar
nixlib-53fa51717658830f466b539a21d5401056b8adce.tar.gz
nixlib-53fa51717658830f466b539a21d5401056b8adce.tar.bz2
nixlib-53fa51717658830f466b539a21d5401056b8adce.tar.lz
nixlib-53fa51717658830f466b539a21d5401056b8adce.tar.xz
nixlib-53fa51717658830f466b539a21d5401056b8adce.tar.zst
nixlib-53fa51717658830f466b539a21d5401056b8adce.zip
Merge pull request #3961 from wkennington/master.grub
nixos/install-grub: Read correct mountpoints
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix8
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl45
-rw-r--r--nixos/tests/installer.nix25
3 files changed, 68 insertions, 10 deletions
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index bc9a155ac95b..0269b95ae1db 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -260,7 +260,7 @@ in
         if cfg.devices == [] then
           throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
         else
-          "PERL5LIB=${makePerlPath [ pkgs.perlPackages.XMLLibXML pkgs.perlPackages.XMLSAX ]} " +
+          "PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ])} " +
           "${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
 
       system.build.grub = grub;
@@ -277,7 +277,11 @@ in
         '') config.boot.loader.grub.extraFiles);
 
     assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
-                    message = "Only grub version 2 provides zfs support";}];
+                    message = "Only grub version 2 provides zfs support";}]
+      ++ flip map cfg.devices (dev: {
+        assertion = hasPrefix "/" dev;
+        message = "Grub devices must be absolute paths, not ${dev}";
+      });
 
     })
 
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 2dad8b36db32..eef81d81484e 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -6,6 +6,7 @@ use File::Basename;
 use File::Path;
 use File::stat;
 use File::Copy;
+use File::Slurp;
 use POSIX;
 use Cwd;
 
@@ -70,14 +71,48 @@ struct(Fs => {
     type => '$',
     mount => '$',
 });
+sub PathInMount {
+    my ($path, $mount) = @_;
+    my @splitMount = split /\//, $mount;
+    my @splitPath = split /\//, $path;
+    if ($#splitPath < $#splitMount) {
+        return 0;
+    }
+    for (my $i = 0; $i <= $#splitMount; $i++) {
+        if ($splitMount[$i] ne $splitPath[$i]) {
+            return 0;
+        }
+    }
+    return 1;
+}
 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 $bestFs = Fs->new(device => "", type => "", mount => "");
+    foreach my $fs (read_file("/proc/self/mountinfo")) {
+        chomp $fs;
+        my @fields = split / /, $fs;
+        my $mountPoint = $fields[4];
+        next unless -d $mountPoint;
+        my @mountOptions = split /,/, $fields[5];
+
+        # Skip the optional fields.
+        my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
+        my $fsType = $fields[$n];
+        my $device = $fields[$n + 1];
+        my @superOptions = split /,/, $fields[$n + 2];
+
+        # Skip the read-only bind-mount on /nix/store.
+        next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
+
+        # Ensure this matches the intended directory
+        next unless PathInMount($dir, $mountPoint);
+
+        # Is it better than our current match?
+        if (length($mountPoint) > length($bestFs->mount)) {
+            $bestFs = Fs->new(device => $device, type => $fsType, mount => $mountPoint);
+        }
     }
-    my @boot = split(/[ \n\t]+/, $dfOut[1]);
-    return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]);
+    return $bestFs;
 }
 struct (Grub => {
     path => '$',
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 66ab2567e197..3e29bc2a45b0 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -35,7 +35,8 @@ let
 
 
   # The configuration to install.
-  makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
+  makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier
+    , readOnly ? true, forceGrubReinstallCount ? 0 }:
     pkgs.writeText "configuration.nix" ''
       { config, pkgs, modulesPath, ... }:
 
@@ -57,6 +58,10 @@ let
           boot.loader.grub.fsIdentifier = "${grubIdentifier}";
         ''}
 
+        boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
+
+        ${optionalString (!readOnly) "nix.readOnlyStore = false;"}
+
         environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
       }
     '';
@@ -198,16 +203,30 @@ let
       $machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/
           or die "nix-env failed";
 
+      # We need to a writable nix-store on next boot
+      $machine->copyFileFromHost(
+          "${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 1; } }",
+          "/etc/nixos/configuration.nix");
+
       # Check whether nixos-rebuild works.
       $machine->succeed("nixos-rebuild switch >&2");
 
       # Test nixos-option.
       $machine->succeed("nixos-option boot.initrd.kernelModules | grep virtio_console");
-      $machine->succeed("nixos-option -d boot.initrd.kernelModules | grep 'List of modules'");
-      $machine->succeed("nixos-option -l boot.initrd.kernelModules | grep qemu-guest.nix");
+      $machine->succeed("nixos-option boot.initrd.kernelModules | grep 'List of modules'");
+      $machine->succeed("nixos-option  boot.initrd.kernelModules | grep qemu-guest.nix");
 
       $machine->shutdown;
 
+      # Check whether a writable store build works
+      $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
+      $machine->waitForUnit("multi-user.target");
+      $machine->copyFileFromHost(
+          "${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 2; } }",
+          "/etc/nixos/configuration.nix");
+      $machine->succeed("nixos-rebuild boot >&2");
+      $machine->shutdown;
+
       # And just to be sure, check that the machine still boots after
       # "nixos-rebuild switch".
       $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });