summary refs log tree commit diff
path: root/nixos/modules/installer/tools/nixos-generate-config.pl
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2014-09-06 16:51:14 +0200
committerVladimír Čunát <vcunat@gmail.com>2014-09-06 16:52:45 +0200
commit06fea81c6e3d71689b59df6e2bbc11fe01ce9056 (patch)
tree5849b904bf1eb3bc8cb28b29729d83a4d0337542 /nixos/modules/installer/tools/nixos-generate-config.pl
parent20be024d1bae622409fa56844b2f8799bbf29bb0 (diff)
parent0c398f60405090743fbdcf14faf1193c642b6328 (diff)
downloadnixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar.gz
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar.bz2
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar.lz
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar.xz
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.tar.zst
nixpkgs-06fea81c6e3d71689b59df6e2bbc11fe01ce9056.zip
Merge recent master into staging
Hydra: ?compare=1150594
Diffstat (limited to 'nixos/modules/installer/tools/nixos-generate-config.pl')
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl45
1 files changed, 40 insertions, 5 deletions
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index c507f7f979f..e8f100d6498 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>&1 |" or die "Failed to execute: $cmd\n";
+    my @ret = <FILE>;
+    close FILE;
+    return ($?, @ret);
+}
 
 # Process the command line.
 my $outDir = "/etc/nixos";
@@ -304,10 +311,13 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
 
     # Maybe this is a bind-mount of a filesystem we saw earlier?
     if (defined $fsByDev{$fields[2]}) {
-        my $path = $fields[3]; $path = "" if $path eq "/";
-        my $base = $fsByDev{$fields[2]};
-        $base = "" if $base eq "/";
-        $fileSystems .= <<EOF;
+        # Make sure this isn't a btrfs subvolume
+        my ($status, @msg) = runCommand("btrfs subvol show $rootDir$mountPoint");
+        if (join("", @msg) =~ /ERROR:/) {
+            my $path = $fields[3]; $path = "" if $path eq "/";
+            my $base = $fsByDev{$fields[2]};
+            $base = "" if $base eq "/";
+            $fileSystems .= <<EOF;
   fileSystems.\"$mountPoint\" =
     { device = \"$base$path\";
       fsType = \"none\";
@@ -315,7 +325,8 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
     };
 
 EOF
-        next;
+            next;
+        }
     }
     $fsByDev{$fields[2]} = $mountPoint;
 
@@ -337,6 +348,30 @@ EOF
         }
     }
 
+    # Is this a btrfs filesystem?
+    if ($fsType eq "btrfs") {
+        my ($status, @id_info) = runCommand("btrfs subvol show $rootDir$mountPoint");
+        if ($status != 0 || join("", @msg) =~ /ERROR:/) {
+            die "Failed to retreive subvolume info for $mountPoint\n";
+        }
+        my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
+        if ($#ids > 0) {
+            die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
+        } elsif ($#ids == 0) {
+            my ($status, @path_info) = runCommand("btrfs subvol list $rootDir$mountPoint");
+            if ($status != 0) {
+                die "Failed to find $mountPoint subvolume id from btrfs\n";
+            }
+            my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
+            if ($#paths > 0) {
+                die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
+            } elsif ($#paths != 0) {
+                die "Btrfs did not return a path for the subvolume at $mountPoint\n";
+            }
+            push @extraOptions, "subvol=$paths[0]";
+        }
+    }
+
     # Emit the filesystem.
     $fileSystems .= <<EOF;
   fileSystems.\"$mountPoint\" =