{ pkgs, lib, hostName, ... }:
{
  # none is the recommended elevator with ZFS (which has its own I/O scheduler)
  # and/or for SSD, whereas HDD could use mq-deadline.
  services.udev.extraRules = ''
    # set none scheduler for non-rotating disks
    ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
    ACTION=="add|change", KERNEL=="nvme[0-9]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
  '';

  boot.supportedFilesystems = [ "zfs" ];
  boot.initrd.supportedFilesystems = [ "zfs" ];
  boot.zfs.requestEncryptionCredentials = lib.mkDefault [ hostName ];

  # Using ZFS together with hibernation (suspend to disk)
  # may cause filesystem corruption.
  # See https://github.com/openzfs/zfs/issues/260
  boot.kernelParams = [ "nohibernate" ];

  # Ensure extra safeguards are active that zfs uses to protect zfs pools.
  boot.zfs.forceImportAll = false;
  boot.zfs.forceImportRoot = false;

  boot.zfs.enableUnstable = false;

  # Enables periodic scrubbing of ZFS pools.
  services.zfs.autoScrub.enable = true;
  services.zfs.autoScrub.interval = "Sun *-*-08..14 00:15:00";

  # According to zpool(8), for consumer hardware
  # periodic manual TRIM is preferred over the automatic TRIM
  # that ZFS implements.
  services.zfs.trim.enable = true;
  services.zfs.trim.interval = "Sun *-*-01..07 00:15:00";

  environment.systemPackages = [
    pkgs.sanoid
  ];
}