Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jkachmar

jkachmar/zfs.md Secret

Last active February 23, 2021 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkachmar/0fee1f810783b0f96ea70e994fe874be to your computer and use it in GitHub Desktop.
Save jkachmar/0fee1f810783b0f96ea70e994fe874be to your computer and use it in GitHub Desktop.

ZFS Pool

Create the zpool on top of the system-pool logical volume.

sudo zpool create -f \
  -o ashift=12 \
  -O acltype=posixacl \
  -O atime=on \
  -O compression=on
  -O com.sun:auto-snapshot=true \
  -O dnodesize=auto \
  -O normalization=formD
  -O mountpoint=none \
  -O relatime=on \
  -O xattr=sa \
  <zpool name> \
  <target partition>
  
zpool list

ashift

The ashift=12 corresponds to a system with native sector size of 4096 bytes; consult the OpenZFS documentation on Advanced Format Disks for more information about this parameter.

Unfortunately I'm not aware of any way to check which value works best here on Linux; some reading online turned up this whitepaper from Intel, which suggests that "most new HDDs and Intel SSDs perform better with a [4KiB] alignment".

See this entry in the Arch Wiki for a few more crumbs of detail (but not much more than that).

acltype and xattr

acltype=posixacl enables the use of POSIX access control levels stored as "extended attributes", and xattr=sa tells ZFS to store these attributes in the file inode rather a hidden subdirectory (as is the default with xattr=on).

See this r/zfs comment for details.

atime and relatime

ZFS will track file access time when atime=on is set, however the default setting can be I/O intensive; relatime=on applies the atime semantics from the EXT4/XFS filesystems to ZFS as a compromise.

See the Arch Wiki ZFS Tuning section for details.

compression

ZFS has a compression=on option which selects one of either the lzjb or lz4 algorithms (depending on whether the lz4_compress feature flag is enabled).

It's worth keeping an eye on zstd compression, which landed in OpenZFS 2.0, although at the time of writing it's too new for me to consider here.

com.sun:auto-snapshot

This flag controls ZFS' auto-snapshotting functionality; by default, if this is not set, the system will not auto-snapshot even if the NixOS module is enabled.

I chose to enable this at the pool-level since I want snapshotting to be opt-out on a per-dataset level (rather than opt-in).

dnodesize

ZFS can automatically determine the dnode size with dnodesize=auto; this is especially useful in concert with the xattr=sa property.

mountpoint=none

Most guides I've seen suggest setting mountpoint=none on the zpool. This setting ensures that the given ZFS construct may not be mounted by the operating system, and should be managed/used entirely by ZFS.

normalization

ZFS doesn't enforce that filenames must be UTF-8 by default; normalization=formD enables this, at the expense of breaking compatibility with anything which may expect a filename that is not valid UTF-8 text.

See this post for details.

ZFS Datasets

Nix Store

Create a ZFS dataset for the Nix store, and mount it.

sudo zfs create -p \
  -o atime=off \
  -o mountpoint=legacy \
  -o com.sun:auto-snapshot=false \
  <zpool name>/nix
  
sudo zfs snapshot <zpool name>/nix@pristine

Unlike the zpool, atime will be disabled here since the Nix store doesn't need to track file access time at all.

Since Nix manages the store entirely on its own, it shouldn't be necessary to enable automatic snapshotting so that can be turned off as well.

Finally, it can be helpful to manually take a "pristine" snapshot of the data before anything files are written.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment