summary refs log tree commit diff
diff options
context:
space:
mode:
authorWill Fancher <elvishjerricco@gmail.com>2023-10-21 11:56:47 -0400
committerWill Fancher <elvishjerricco@gmail.com>2023-10-22 20:07:55 -0400
commit0425c4de6d1ebade3c082698a9d47b2f1b0080db (patch)
tree8bba42fac5190005dc6bf8462d01f53396c115c1
parent7c9cc5a6e5d38010801741ac830a3f8fd667a7a0 (diff)
downloadnixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar.gz
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar.bz2
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar.lz
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar.xz
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.tar.zst
nixpkgs-0425c4de6d1ebade3c082698a9d47b2f1b0080db.zip
systemd-stage-1: bcachefs decryption
-rw-r--r--nixos/modules/tasks/filesystems/bcachefs.nix50
-rw-r--r--nixos/tests/installer-systemd-stage-1.nix2
-rw-r--r--nixos/tests/installer.nix4
3 files changed, 46 insertions, 10 deletions
diff --git a/nixos/modules/tasks/filesystems/bcachefs.nix b/nixos/modules/tasks/filesystems/bcachefs.nix
index 19ef188ce78..b90ff894624 100644
--- a/nixos/modules/tasks/filesystems/bcachefs.nix
+++ b/nixos/modules/tasks/filesystems/bcachefs.nix
@@ -34,17 +34,43 @@ let
     }
   '';
 
-  openCommand = name: fs:
-    let
-      # we need only unlock one device manually, and cannot pass multiple at once
-      # remove this adaptation when bcachefs implements mounting by filesystem uuid
-      # also, implement automatic waiting for the constituent devices when that happens
-      # bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
-      firstDevice = head (splitString ":" fs.device);
-    in
-      ''
-        tryUnlock ${name} ${firstDevice}
+  # we need only unlock one device manually, and cannot pass multiple at once
+  # remove this adaptation when bcachefs implements mounting by filesystem uuid
+  # also, implement automatic waiting for the constituent devices when that happens
+  # bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
+  firstDevice = fs: head (splitString ":" fs.device);
+
+  openCommand = name: fs: ''
+    tryUnlock ${name} ${firstDevice fs}
+  '';
+
+  mkUnits = prefix: name: fs: let
+    mountUnit = "${utils.escapeSystemdPath (prefix + (lib.removeSuffix "/" fs.mountPoint))}.mount";
+    device = firstDevice fs;
+    deviceUnit = "${utils.escapeSystemdPath device}.device";
+  in {
+    name = "unlock-bcachefs-${utils.escapeSystemdPath fs.mountPoint}";
+    value = {
+      description = "Unlock bcachefs for ${fs.mountPoint}";
+      requiredBy = [ mountUnit ];
+      before = [ mountUnit ];
+      bindsTo = [ deviceUnit ];
+      after = [ deviceUnit ];
+      unitConfig.DefaultDependencies = false;
+      serviceConfig = {
+        Type = "oneshot";
+        ExecCondition = "${pkgs.bcachefs-tools}/bin/bcachefs unlock -c \"${device}\"";
+        Restart = "on-failure";
+        RestartMode = "direct";
+        # Ideally, this service would lock the key on stop.
+        # As is, RemainAfterExit doesn't accomplish anything.
+        RemainAfterExit = true;
+      };
+      script = ''
+        ${config.boot.initrd.systemd.package}/bin/systemd-ask-password --timeout=0 "enter passphrase for ${name}" | exec ${pkgs.bcachefs-tools}/bin/bcachefs unlock "${device}"
       '';
+    };
+  };
 
 in
 
@@ -59,6 +85,8 @@ in
 
       # use kernel package with bcachefs support until it's in mainline
       boot.kernelPackages = pkgs.linuxPackages_testing_bcachefs;
+
+      systemd.services = lib.mapAttrs' (mkUnits "") (lib.filterAttrs (n: fs: (fs.fsType == "bcachefs") && (!utils.fsNeededForBoot fs)) config.fileSystems);
     }
 
     (mkIf ((elem "bcachefs" config.boot.initrd.supportedFilesystems) || (bootFs != {})) {
@@ -79,6 +107,8 @@ in
       '';
 
       boot.initrd.postDeviceCommands = commonFunctions + concatStrings (mapAttrsToList openCommand bootFs);
+
+      boot.initrd.systemd.services = lib.mapAttrs' (mkUnits "/sysroot") bootFs;
     })
   ]);
 }
diff --git a/nixos/tests/installer-systemd-stage-1.nix b/nixos/tests/installer-systemd-stage-1.nix
index 85155a6c682..8f10a461d1c 100644
--- a/nixos/tests/installer-systemd-stage-1.nix
+++ b/nixos/tests/installer-systemd-stage-1.nix
@@ -8,6 +8,8 @@
   # them when fixed.
   inherit (import ./installer.nix { inherit system config pkgs; systemdStage1 = true; })
     # bcache
+    bcachefsSimple
+    bcachefsEncrypted
     btrfsSimple
     btrfsSubvolDefault
     btrfsSubvolEscape
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 3268a16967d..c21f5608940 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -918,6 +918,10 @@ in {
     enableOCR = true;
     preBootCommands = ''
       machine.start()
+      # Enter it wrong once
+      machine.wait_for_text("enter passphrase for ")
+      machine.send_chars("wrong\n")
+      # Then enter it right.
       machine.wait_for_text("enter passphrase for ")
       machine.send_chars("password\n")
     '';