summary refs log tree commit diff
path: root/nixos/modules/tasks/filesystems.nix
diff options
context:
space:
mode:
authorNikolay Amiantov <ab@fmap.me>2016-08-27 14:34:55 +0400
committerGitHub <noreply@github.com>2016-08-27 14:34:55 +0400
commit3f70fcd4c1512345a5a8a5e41da8a83839a1b16e (patch)
tree04ba4533ff21a3736e79f47cc9258fd4dfe626e8 /nixos/modules/tasks/filesystems.nix
parent44289f81e98f1d1217209741b1e1e631a9511a75 (diff)
parentb267785c43547dbe854c994a91b9f012c9b7812f (diff)
downloadnixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar.gz
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar.bz2
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar.lz
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar.xz
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.tar.zst
nixpkgs-3f70fcd4c1512345a5a8a5e41da8a83839a1b16e.zip
Merge pull request #11484 from oxij/nixos-toposort-filesystems
lib: add toposort, nixos: use toposort for fileSystems to properly support bind and move mounts
Diffstat (limited to 'nixos/modules/tasks/filesystems.nix')
-rw-r--r--nixos/modules/tasks/filesystems.nix39
1 files changed, 30 insertions, 9 deletions
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 5a9406101ac..f146448200f 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -5,7 +5,16 @@ with utils;
 
 let
 
-  fileSystems = attrValues config.fileSystems;
+  fileSystems' = toposort fsBefore (attrValues config.fileSystems);
+
+  fileSystems = if fileSystems' ? "result"
+                then # use topologically sorted fileSystems everywhere
+                     fileSystems'.result
+                else # the assertion below will catch this,
+                     # but we fall back to the original order
+                     # anyway so that other modules could check
+                     # their assertions too
+                     (attrValues config.fileSystems);
 
   prioOption = prio: optionalString (prio != null) " pri=${toString prio}";
 
@@ -162,6 +171,17 @@ in
 
   config = {
 
+    assertions = let
+      ls = sep: concatMapStringsSep sep (x: x.mountPoint);
+    in [
+      { assertion = ! (fileSystems' ? "cycle");
+        message = "The ‘fileSystems’ option can't be topologically sorted: mountpoint dependency path ${ls " -> " fileSystems'.cycle} loops to ${ls ", " fileSystems'.loops}";
+      }
+    ];
+
+    # Export for use in other modules
+    system.build.fileSystems = fileSystems;
+
     boot.supportedFilesystems = map (fs: fs.fsType) fileSystems;
 
     # Add the mount helpers to the system path so that `mount' can find them.
@@ -180,7 +200,7 @@ in
         # in your /etc/nixos/configuration.nix file.
 
         # Filesystems.
-        ${flip concatMapStrings fileSystems (fs:
+        ${concatMapStrings (fs:
             (if fs.device != null then fs.device
              else if fs.label != null then "/dev/disk/by-label/${fs.label}"
              else throw "No device specified for mount point ‘${fs.mountPoint}’.")
@@ -191,7 +211,7 @@ in
             + " " + (if skipCheck fs then "0" else
                      if fs.mountPoint == "/" then "1" else "2")
             + "\n"
-        )}
+        ) fileSystems}
 
         # Swap devices.
         ${flip concatMapStrings config.swapDevices (sw:
@@ -211,14 +231,15 @@ in
 
         formatDevice = fs:
           let
-            mountPoint' = escapeSystemdPath fs.mountPoint;
-            device' = escapeSystemdPath fs.device;
+            mountPoint' = "${escapeSystemdPath fs.mountPoint}.mount";
+            device'  = escapeSystemdPath fs.device;
+            device'' = "${device}.device";
           in nameValuePair "mkfs-${device'}"
           { description = "Initialisation of Filesystem ${fs.device}";
-            wantedBy = [ "${mountPoint'}.mount" ];
-            before = [ "${mountPoint'}.mount" "systemd-fsck@${device'}.service" ];
-            requires = [ "${device'}.device" ];
-            after = [ "${device'}.device" ];
+            wantedBy = [ mountPoint' ];
+            before = [ mountPoint' "systemd-fsck@${device'}.service" ];
+            requires = [ device'' ];
+            after = [ device'' ];
             path = [ pkgs.utillinux ] ++ config.system.fsPackages;
             script =
               ''