···34 }
35 '';
3637- openCommand = name: fs:
38- let
39- # we need only unlock one device manually, and cannot pass multiple at once
40- # remove this adaptation when bcachefs implements mounting by filesystem uuid
41- # also, implement automatic waiting for the constituent devices when that happens
42- # bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
43- firstDevice = head (splitString ":" fs.device);
44- in
45- ''
46- tryUnlock ${name} ${firstDevice}
00000000000000000000000047 '';
004849in
50···5960 # use kernel package with bcachefs support until it's in mainline
61 boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
0062 }
6364 (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) {
···79 '';
8081 boot.initrd.postDeviceCommands = commonFunctions + concatStrings (mapAttrsToList openCommand bootFs);
0082 })
83 ]);
84}
···34 }
35 '';
3637+ # we need only unlock one device manually, and cannot pass multiple at once
38+ # remove this adaptation when bcachefs implements mounting by filesystem uuid
39+ # also, implement automatic waiting for the constituent devices when that happens
40+ # bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
41+ firstDevice = fs: head (splitString ":" fs.device);
42+43+ openCommand = name: fs: ''
44+ tryUnlock ${name} ${firstDevice fs}
45+ '';
46+47+ mkUnits = prefix: name: fs: let
48+ mountUnit = "${utils.escapeSystemdPath (prefix + (lib.removeSuffix "/" fs.mountPoint))}.mount";
49+ device = firstDevice fs;
50+ deviceUnit = "${utils.escapeSystemdPath device}.device";
51+ in {
52+ name = "unlock-bcachefs-${utils.escapeSystemdPath fs.mountPoint}";
53+ value = {
54+ description = "Unlock bcachefs for ${fs.mountPoint}";
55+ requiredBy = [ mountUnit ];
56+ before = [ mountUnit ];
57+ bindsTo = [ deviceUnit ];
58+ after = [ deviceUnit ];
59+ unitConfig.DefaultDependencies = false;
60+ serviceConfig = {
61+ Type = "oneshot";
62+ ExecCondition = "${pkgs.bcachefs-tools}/bin/bcachefs unlock -c \"${device}\"";
63+ Restart = "on-failure";
64+ RestartMode = "direct";
65+ # Ideally, this service would lock the key on stop.
66+ # As is, RemainAfterExit doesn't accomplish anything.
67+ RemainAfterExit = true;
68+ };
69+ script = ''
70+ ${config.boot.initrd.systemd.package}/bin/systemd-ask-password --timeout=0 "enter passphrase for ${name}" | exec ${pkgs.bcachefs-tools}/bin/bcachefs unlock "${device}"
71 '';
72+ };
73+ };
7475in
76···8586 # use kernel package with bcachefs support until it's in mainline
87 boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
88+89+ systemd.services = lib.mapAttrs' (mkUnits "") (lib.filterAttrs (n: fs: (fs.fsType == "bcachefs") && (!utils.fsNeededForBoot fs)) config.fileSystems);
90 }
9192 (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) {
···107 '';
108109 boot.initrd.postDeviceCommands = commonFunctions + concatStrings (mapAttrsToList openCommand bootFs);
110+111+ boot.initrd.systemd.services = lib.mapAttrs' (mkUnits "/sysroot") bootFs;
112 })
113 ]);
114}
+2
nixos/tests/installer-systemd-stage-1.nix
···8 # them when fixed.
9 inherit (import ./installer.nix { inherit system config pkgs; systemdStage1 = true; })
10 # bcache
0011 btrfsSimple
12 btrfsSubvolDefault
13 btrfsSubvolEscape
···937 enableOCR = true;
938 preBootCommands = ''
939 machine.start()
940+ # Enter it wrong once
941+ machine.wait_for_text("enter passphrase for ")
942+ machine.send_chars("wrong\n")
943+ # Then enter it right.
944 machine.wait_for_text("enter passphrase for ")
945 machine.send_chars("password\n")
946 '';