···55let
66 fileSystems = config.system.build.fileSystems ++ config.swapDevices;
77 encDevs = filter (dev: dev.encrypted.enable) fileSystems;
88- keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs;
99- keylessEncDevs = filter (dev: dev.encrypted.keyFile == null) encDevs;
88+99+ # With scripted initrd, devices with a keyFile have to be opened
1010+ # late, after file systems are mounted, because that could be where
1111+ # the keyFile is located. With systemd initrd, each individual
1212+ # systemd-cryptsetup@ unit has RequiresMountsFor= to delay until all
1313+ # the mount units for the key file are done; i.e. no special
1414+ # treatment is needed.
1515+ lateEncDevs =
1616+ if config.boot.initrd.systemd.enable
1717+ then { }
1818+ else filter (dev: dev.encrypted.keyFile != null) encDevs;
1919+ earlyEncDevs =
2020+ if config.boot.initrd.systemd.enable
2121+ then encDevs
2222+ else filter (dev: dev.encrypted.keyFile == null) encDevs;
2323+1024 anyEncrypted =
1125 foldr (j: v: v || j.encrypted.enable) false encDevs;
1226···3953 type = types.nullOr types.str;
4054 description = lib.mdDoc ''
4155 Path to a keyfile used to unlock the backing encrypted
4242- device. At the time this keyfile is accessed, the
4343- `neededForBoot` filesystems (see
4444- `fileSystems.<name?>.neededForBoot`)
4545- will have been mounted under `/mnt-root`,
4646- so the keyfile path should usually start with "/mnt-root/".
5656+ device. When systemd stage 1 is not enabled, at the time
5757+ this keyfile is accessed, the `neededForBoot` filesystems
5858+ (see `utils.fsNeededForBoot`) will have been mounted under
5959+ `/mnt-root`, so the keyfile path should usually start with
6060+ "/mnt-root/". When systemd stage 1 is enabled,
6161+ `fsNeededForBoot` file systems will be mounted as needed
6262+ under `/sysroot`, and the keyfile will not be accessed until
6363+ its requisite mounts are done.
4764 '';
4865 };
4966 };
···6279 };
63806481 config = mkIf anyEncrypted {
6565- assertions = map (dev: {
6666- assertion = dev.encrypted.label != null;
6767- message = ''
6868- The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set
6969- '';
7070- }) encDevs;
8282+ assertions = concatMap (dev: [
8383+ {
8484+ assertion = dev.encrypted.label != null;
8585+ message = ''
8686+ The filesystem for ${dev.mountPoint} has encrypted.enable set to true, but no encrypted.label set
8787+ '';
8888+ }
8989+ {
9090+ assertion =
9191+ config.boot.initrd.systemd.enable -> (
9292+ dev.encrypted.keyFile == null
9393+ || !lib.any (x: lib.hasPrefix x dev.encrypted.keyFile) ["/mnt-root" "$targetRoot"]
9494+ );
9595+ message = ''
9696+ Bad use of '/mnt-root' or '$targetRoot` in 'keyFile'.
9797+9898+ When 'boot.initrd.systemd.enable' is enabled, file systems
9999+ are mounted at '/sysroot' instead of '/mnt-root'.
100100+ '';
101101+ }
102102+ ]) encDevs;
7110372104 boot.initrd = {
73105 luks = {
74106 devices =
75107 builtins.listToAttrs (map (dev: {
76108 name = dev.encrypted.label;
7777- value = { device = dev.encrypted.blkDev; };
7878- }) keylessEncDevs);
109109+ value = { device = dev.encrypted.blkDev; inherit (dev.encrypted) keyFile; };
110110+ }) earlyEncDevs);
79111 forceLuksSupportInInitrd = true;
80112 };
81113 postMountCommands =
82114 concatMapStrings (dev:
83115 "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n"
8484- ) keyedEncDevs;
116116+ ) lateEncDevs;
85117 };
86118 };
87119}