return 12; // good enough for now

ZFS on NixOS

I’ve recently set up a new home server to act as a NAS and fulfil other misc responsibilities. It’s got 4x6TB HDDs in raidz configuration. Here’s how I got ZFS set up on NixOS.

Install NixOS and enable ZFS

Install NixOS as usual, then add ZFS support to your configuration.nix.

# configuration.nix

boot.supportedFilesystems = [ "zfs" ];
boot.zfs.forceImportRoot = false;
networking.hostId = "6d778fb4"; # head -c4 /dev/urandom | od -A none -t x4

Create ZFS pool and datasets

Once rebuilt, find the names of the drives you want to add to your pool.

$ ls /dev/disk/by-id

 ata-ST6000VN001-2BB186_ZRxxxxxx
 ata-ST6000VN001-2BB186_ZRxxxxxx
 ata-TOSHIBA_HDWG460_32xxxxxxxxxx
 ata-TOSHIBA_HDWG460_33xxxxxxxxxx

Now create the pool with zpool create. The [ArchWiki] says to always set ashift=12 so let’s just do that.

$ zpool create -f -o ashift=12 -m /mnt/<poolname> <poolname> \
    raidz \
    ata-ST6000VN001-2BB186_ZRxxxxxx \
    ata-ST6000VN001-2BB186_ZRxxxxxx \
    ata-TOSHIBA_HDWG460_32xxxxxxxxxx \

I’m chosing ’taskpool’ for the pool name as the machine is called Taskmaster

Then create the datasets you want. For now, I’m just creating one for media. I’ll add more as I go.

$ zfs create poolname/media

The pool and dataset you created can be seen under the /mnt directory

$ ls /mnt

To ensure the pool and datasets are mounted at boot you need to add the required lines to your hardware-configuration.nix. You can auto generate a config with:

$ nixos-generate-config  # Add --show-hardware-config if you're not using
                         # /etc/nixos/hardware-configuration.nix

Or you can manually add the lines yourself

# hardware-configuration.nix

fileSystems."/mnt/taskpool" =
  { device = "taskpool";
    fsType = "zfs";

fileSystems."/mnt/taskpool/media" =
  { device = "taskpool/media";
    fsType = "zfs";

Before rebuilding the config you’ll need to set the mountpoint to legacy

$ zfs set mountpoint=legacy <poolname>

If you don’t set mountpoint=legacy you’ll likely see the following error and get dropped in to emergency recovery mode on the next boot.

A dependency job for failed. See 'journalctl -xe' for
details. Job for canceled

Getting out of recovery mode doesn’t seem to be a problem, just run that command and then reboot. All should be well again.