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 \
    ata-TOSHIBA_HDWG460_33xxxxxxxxxx

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 local-fs.target failed. See 'journalctl -xe' for
details. Job for sysinit.target 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.

Elsewhere