Boot.initrd.luks dependent devices not working

I have a USB key (encrypted by password) to unlock my root partition with luks.

In configuration, I unlock the USB key in boot.intrd.luks as /dev/mapper/usb and then use it as key file for another luks device:

boot.initrd.systemd.enable = true;
boot.initrd.luks.devices = {
  usb.device = "/dev/disk/by-uuid/...";
  # root partition
  root = {
    device = "/dev/disk/by-uuid/...";
	keyFile = "/dev/mapper/usb";
	crypttabExtraOpts = [
	  "plain"
	  "keyfile-offset=..."
	];
  }
}

It works for a while before I updated nixpkgs yesterday. After the update, my system gets stuck at boot waiting for /dev/mapper/usb after I type the password to unlock it.

Any idea why it doesn’t work anymore?

Thanks in advance.

see: Revert "systemd: drop 0001-Start-device-units-for-uninitialised-encrypted-devic.patch" by ipetkov · Pull Request #525118 · NixOS/nixpkgs · GitHub

systemd actually prevents this use case normally, but NixOS has always patched that out. We recently went through an effort to eliminate as many of the downstream patches we have for systemd as possible, which included that one. So now we match other distros and /etc/crypttab (which boot.initrd.luks.devices is a frontend for with systemd stage 1) no longer works with this.

You can restore the old behavior with this if you really want:

boot.initrd.services.udev.packages = [
  (pkgs.writeTextFile {
    # We need to be after 99-systemd.rules, so we bump to A0-*
    name = "A0-local.rules";
    destination = "/etc/udev/rules.d/A0-local.rules";
    text = ''
      SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="1"
    '';
  })
];

But my real suggestion is to just put a small file system like ext4 on the other LUKS volume and use:

keyFile = "/key:/dev/mapper/usb";

Which tells systemd that, after usb is decrypted, it can mount the FS stored on it and find a key file inside at /key.

Thank you so much for the pointer! That’s exactly what causes the problem in my configuration. I have applied the code in your reply and it works perfectly.

I decided not to use a filesystem at the moment because the rest of my USB is already used for other purposes and creating a filesystem will change the data layout on it. But it is indeed a cleaner solution than a udev rule patch.