diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 6f0f62546a018a..bae85ac39491b0 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -113,56 +113,16 @@ sub runCommand { 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; -} # Figure out what filesystem is used for the directory with init/initrd/kernel files sub GetFs { my ($dir) = @_; - 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]; - 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 bind-mount on /nix/store. - next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions); - # Skip mount point generated by systemd-efi-boot-generator? - next if $fsType eq "autofs"; - - # Ensure this matches the intended directory - next unless PathInMount($dir, $mountPoint); - - # Is it better than our current match? - if (length($mountPoint) > length($bestFs->mount)) { - - # -d performs a stat, which can hang forever on network file systems, - # so we only make this call last, when it's likely that this is the mount point we need. - next unless -d $mountPoint; - - $bestFs = Fs->new(device => $device, type => $fsType, mount => $mountPoint); - } + my ($status, @devInfo) = runCommand("@utillinux@/bin/findmnt", "-n", "-v", "-o", "SOURCE,FSTYPE,TARGET", "-T", @{[$dir]}); + if ($status != 0 || $#devInfo != 1) { + die "Failed to get file system (returned $status) for @{[$dir]}"; } - return $bestFs; + my @fields = split /\s+/, $devInfo[0]; + return Fs->new(device => $fields[0], type => $fields[1], mount => $fields[2]); } struct (Grub => { path => '$',