My home contains multiple FreeBSD machines – laptops, desktops, single-board-computers – which can benefit from sharing storage. In particular, I really only need one copy of the FreeBSD source tree (plus some work-trees for different branches) and one copy of the ports tree and distfiles. This blog post is my notes on setting that up.

These notes are for my home infrastructure, where I trust the machines that are plugged into the wired network, simply because I can see the switch from my desk and know where all the wires go. I’m not taking notes for security.

All of these notes build on the FreeBSD Handbook chapters on ZFS and Network Servers.

Server Side NFS Setup

Configure the server for NFS with sysrc rpcbind_enable=YES nfs_server_enable=YES mountd_enable=YES and then start NFS services service nfsd start . This enables NFS services also after a reboot. To turn them off again, use sysrc and swap NO for YES.

Client Side NFS Setup

Enable NFS client with sysrc nfs_client_enable=YES and then start NFS services with service nfsclient start . This enables NFS services also after a reboot. To turn them off again, use sysrc and swap NO for YES.

Per-Filesystem Setup

For each filesystem that needs to be shared, go through these steps. It is easiest to do this with one filesystem per mountpoint (mountpoint on the client side, so possibly /usr/ports, /usr/src and /usr/obj which want three filesystems on the server side’ however, this does not work well with git work-trees).

Filling the filesystems that need sharing is outside of the scope of these notes, but

  • The ports tree lives in git and can be anonymously cloned. There is a nice guide (PDF) as well.
  • The source tree contains the whole operating system, lives in git and can be anonymously cloned.

Server Side

  • Create a ZFS filesystem, say zdata/export/ports. It doesn’t really matter where it is mounted.
  • Turn on NFS sharing on this ZFS filesystem (this step might be redundant), zfs set sharenfs=on zdata/export/ports .
  • Set options for NFS sharing with no attention to security at all, zfs set sharenfs="-network=192.168.56.0/24 -maproot=root" zdata/export/ports .
  • Don’t bother with /etc/exports, since we’re using ZFS. Turn on sharing for the filesystem with zfs share zdata/export/ports .

Client Side

Just mount the remote filesystem (read-only here) with mount -o ro 192.168.56.1:zdata/export/ports /usr/ports .

When troubleshooting (permission denied), check the IP address of the client is in the network specified by the NFS share on the server.

Mounting a subdirectory of an export isn’t possible. In that case, mount the exported filesystem somewhere temporary (e.g. /mnt/export) and then use mount -t nullfs -o ro /mnt/export/subdir /some/path .

System Updates Over NFS

For me the main reason to set this up is that I can git clone src, build the FreeBSD operating system once, and then share the build results across multiple machines by mounting /usr/src and /usr/obj from the machine that did the build. It saves considerable compile time, even if the resulting installation over the network is a lot slower than from a local md(8) to an NVMe drive.

One minor gotcha is that make installkernel complains a lot about read-only filesystems. But that’s only a complaint, and everything installs normally.

Subsequent mergemaster is normal and make installworld complains in the same way.