Zfs + systemd-boot

I use a mirrored zpool, no separate boot pool, no special config with systemd-boot issueless, as an example

export d0="/dev/nvme0n1"
export d1="/dev/nvme1n1"

wipefs $d0; sgdisk -z $d0; sgdisk -og $d0
wipefs $d1; sgdisk -z $d1; sgdisk -og $d1

sgdisk --new 1::+512M --typecode=1:EF00 --change-name=1:'ESP0' $d0
sgdisk --new 1::+512M --typecode=1:EF00 --change-name=1:'ESP1' $d1

sgdisk --new 2::+1857G --typecode=2:BF01 --change-name=2:'rpvol0' $d0
sgdisk --new 2::+1857G --typecode=2:BF01 --change-name=2:'rpvol1' $d1

partprobe
udevadm settle

mkfs.vfat -F32 -nESP1 /dev/disk/by-partlabel/ESP0
mkfs.vfat -F32 -nESP2 /dev/disk/by-partlabel/ESP1

zpool create                  \
      -o ashift=12            \
      -o autotrim=on          \
      -o acltype=posixacl     \
      -o compression=on       \
      -o dnodesize=auto       \
      -o normalization=formD  \
      -o encryption=on        \
      -o keyformat=passphrase \
      -o keylocation=prompt   \
      -o relatime=on          \
      -o xattr=sa             \
      -o mountpoint=none rootp mirror /dev/disk/by-partlabel/rpvol0 /dev/disk/by-partlabel/rpvol1

zfs create -o mountpoint=legacy -o compression=lz4 rootp/nixos
# and all others

mount -t zfs rootp/nixos /mnt
noglob mkdir -p /mnt/efiboot/{efi1,efi2}
mount -t vfat -o iocharset=iso8859-1 /dev/disk/by-label/ESP1 /mnt/efiboot/efi1
mount -t vfat -o iocharset=iso8859-1 /dev/disk/by-label/ESP2 /mnt/efiboot/efi2

# all other mounts
# generate config, if needed, install etc

then for relevant NixOS config

  boot = {
    loader = {
      systemd-boot = {
        enable = true;

        extraInstallCommands = ''
          mount -t vfat -o iocharset=iso8859-1 /dev/disk/by-label/ESP1 /efiboot/efi1
          mount -t vfat -o iocharset=iso8859-1 /dev/disk/by-label/ESP2 /efiboot/efi2
          cp -r /efiboot/efi1/* /efiboot/efi2
        '';
      }; # systemd-boot

      generationsDir.copyKernels = true;

      efi = {
        canTouchEfiVariables = true;
        efiSysMountPoint = "/efiboot/efi1";
      }; # efi
    }; # loader

    kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;

    initrd = {
      kernelModules = [ "zfs" ];

      postDeviceCommands = ''
        zpool import -lf rootp
      ''; # postDeviceCommands
  }; # initrd

  supportedFilesystems = [ "zfs" ];

    zfs = {
      devNodes = "/dev/disk/by-partlabel";
    }; # zfs

  }; # boot

############################################

  fileSystems."/" =
    { device = "kwsrp/nixos";
      fsType = "zfs";
      neededForBoot = true;
    };

  fileSystems."/efiboot/efi2" =
    { device = "/dev/disk/by-label/ESP2";
      fsType = "vfat";
      options = [ "X-mount.mkdir" "iocharset=iso8859-1" ];
    };

Nothing else. No need for a separate boot pool with limited features for a grub-reachable extra stages, the kernel is in the EFI partition, in the initrd the zpool get unlocked/mounted (also useful if you have other pools encrypted with keys in some files stored for instance on a USB key).

3 Likes