summary refs log tree commit diff
path: root/nixos/modules/system/boot/loader
diff options
context:
space:
mode:
authorWilliam A. Kennington III <william@wkennington.com>2014-09-03 14:40:27 -0700
committerWilliam A. Kennington III <william@wkennington.com>2014-09-04 10:31:39 -0700
commitf73f7ccc6e0b17d08d2ef689b76755769d3663b4 (patch)
treebe47c5c40df1ac7c7754561584a5e0b3a6f381fe /nixos/modules/system/boot/loader
parent4d104542e987533f61cf6fb70cb970fc94e367b9 (diff)
downloadnixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar.gz
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar.bz2
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar.lz
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar.xz
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.tar.zst
nixlib-f73f7ccc6e0b17d08d2ef689b76755769d3663b4.zip
nixos/install-grub: Read correct mountpoints
Diffstat (limited to 'nixos/modules/system/boot/loader')
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl45
2 files changed, 41 insertions, 6 deletions
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index bc9a155ac95b..892cd995a519 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;
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 => '$',