■ Premises
As pretty much any other UNIX system, NetBSD provides solid in-kernel NFS support. See nfsssvc(2)
Since I only run Windows occasionally (mainly for MS-Office or MATLAB) and all of my machines either run NetBSD, Slackware or Tribblix, it makes sense for me to opt for NFS as a distributed file system protocol to share files from my server over the local network.
■ Server setup
(Also Refer to 29.1. The Network File System (NFS))
1. Preliminary tasks
First of all, if you run a custom kernel, make sure to have support built-in, by inspecting your config:
$ config -x /netbsd | grep NFS
Which should at least return:
###> file-system NFS # Network File System client
###> options NFSSERVER # Network File System server
In /etc/sysctl.conf, set the number of kernel threads created to serve asynchronous NFS I/O requests:
# Number of kernel threads to use for NFS client
vfs.nfs.iothreads=6
2. Configure a NFS server
I want make the following ZFS datasets available on the local network:
NAME USED AVAIL REFER MOUNTPOINT
zfs/data 6.96G 493G 6.96G /zfs/data # pdfs, misc
zfs/music 22.9G 77.1G 22.9G /zfs/music # music
zfs/p2p 108G 1.61T 108G /zfs/p2p # torrent destdir
zfs/pkg 3.95G 96.0G 3.95G /zfs/pkg # binary packages
First, create an /etc/exports file with the following content:
/zfs/data -alldirs -maproot=vms -network 192.168.1.0 -mask 255.255.255.0
/zfs/music -alldirs -maproot=vms -network 192.168.1.0 -mask 255.255.255.0
/zfs/p2p -alldirs -maproot=vms -network 192.168.1.0 -mask 255.255.255.0
/zfs/pkg -alldirs -maproot=vms -network 192.168.1.0 -mask 255.255.255.0
This tells mountd(8) to serve the datasets (and all subdirectories) for NFS mount requests coming from local client machines. The client's root user shall access the shared directories as if it was user vms
on the server. See exports(5).
Now, let's look at relevant rc.d services.
Within /etc/rc.conf:
rpcbind=YES # required for Sun RPC services like lockd and statd
mountd=YES # handle file-system mount requests
nfs_server=YES # rcvar for nfsd
nfsd_flags='-n6' # NFS I/O threads to create
lockd=YES # handle record-locking operations on NFS file
statd=YES # crash and recovery functions for the lock manager
Note: the lockd and statd services are handled by the /etc/rc.d/nfslocking rc script.
Enable the services:
$ for var in rpcbind mountd nfsd nfslocking
> do service $var start
> done
3. Firewall settings
We need to tell NPF to allow inbound traffic on NFS/RCP services coming from the local network.
First let's check which ports were assigned to RPC services:
$ rpcinfo -p
program vers proto port service
100024 1 udp 1014 status
100024 1 tcp 1017 status
100021 0 udp 1013 nlockmgr
100021 1 udp 1013 nlockmgr
100021 3 udp 1013 nlockmgr
100021 4 udp 1013 nlockmgr
100021 0 tcp 1016 nlockmgr
100021 1 tcp 1016 nlockmgr
100021 3 tcp 1016 nlockmgr
100021 4 tcp 1016 nlockmgr
100005 1 udp 1012 mountd
100005 3 udp 1012 mountd
100005 1 tcp 1015 mountd
100005 3 tcp 1015 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
Then, by editing /etc/npf.conf, make sure these ports are opened to local clients:
$LAN = { 192.168.1.0/24 }
$services_nfs = { rpcbind, nfsd, 1012-1017 }
pass stateful in final from $LAN to $int_if port $services_nfs apply "log"
Atomically update the NPF ruleset:
$ npfctl reload
Now if everything went well, you should see the datasets available as NFS shares by running the showmount(8) command from a client machine:
$ showmount -e homelab
Export list for homelab:
/zfs/data 192.168.1.0
/zfs/music 192.168.1.0
/zfs/p2p 192.168.1.0
/zfs/pkg 192.168.1.0
Note: the server's internal address is assigned the name 'homelab' on the client's /etc/hosts file.
■ Client setup
1. Make sure to have:
rpcbind=yes
nfs_client=yes
lockd=yes
statd=yes
inside /etc/rc.conf.
2. Start the services:
$ service rpcbind start
$ service nfslocking start
■ Automounting NFS shares on NetBSD
A NetBSD NFS client is probably less common than a NFS server.
But what if we run NetBSD on the desktop?
Let's see the available options to automatize mounting NFS shares on NetBSD.
1. fstab
We can use /etc/fstab to define mount points and mount options on the client machine:
homelab:/zfs/data /net/data nfs rw,noauto,intr,timeo=14 0 0
homelab:/zfs/music /net/music nfs rw,noauto,intr,timeo=14 0 0
homelab:/zfs/p2g /net/p2p nfs rw,noauto,intr,timeo=14 0 0
homelab:/zfs/pkg /net/pkg nfs rw,noauto,intr,timeo=14 0 0
Notes:
The intr
mount option allows NFS requests to be interrupted if the server goes down or cannot be reached. Will avoid hanging.
timeo=n
defines the time (in tenths of a second) the NFS client waits for a response before it retries an NFS request. Default is 30.
It is highly advisable to use noauto
in order to avoid boot failures while mounting filesystems if the server is unreacheable (e.g. outside
of the local netwotk)
You may want to also play with rsize=num
and wsize=num
, which define the maximum number of bytes in each READ/WRITE request that the
NFS client can receive/send when communicating with a NFS server. On NetBSD this is set by default to 32K on amd64 and aarch64, to 8192 on
other platforms.
With such entries on fstab, all that's required to mount any shared dataset is:
$ mount <mountpoint>
For example, to mount homelab:/zfs/music, I'd use:
$ mount /net/music
2. amd(8)
We can use amd(8) on NetBSD to automount NFS shares.
From the man page:
Amd is a daemon that automatically mounts filesystems whenever a file
or directory within that filesystem is accessed. Filesystems are auto-
matically unmounted when they appear to have become quiescent.
First, a map file is needed to tell amd how to resolve the lookup on the target filesystem to mount.
In this case I'll add a second [ /map ]
section to my /etc/amd.conf, telling amd to use the mapfile named 'net' to mount the NFS-shared dataset under /net:
[ global ]
karch = amd64
auto_dir = /amd
unmount_on_exit = no
restart_mounts = yes
browsable_dirs = yes
print_pid = no
print_version = no
dismount_interval = 5
cache_duration = 5
localhost_address = 127.0.0.1
log_file = /var/log/amd.log
log_options = all
search_path = /etc/amd
map_type = file
map_options = cache:=all
[ /media ]
map_name = media
[ /net ]
map_name = net
Make sure that the required directories are in place.
amd scans the $search_path
for map files, uses $auto_dir
to mount filesystems, and the directory specified by the [ /map ]
section to make them available as NFS shares.
$ for dir in /amd /etc/amd /net
> do [ -d "$dir" ] || mkdir $dir
> done
A sample /etc/amd/net mapfile for NFS shares is provided below:
/defaults type:=host;rhost:=${key};fs:=${autodir}/${rhost}/root
pub type:=host;rhost:=homelab;fs:=${autodir}/${rhost}/root
Such map will mount any filesystems shared via NFS by the host homelab inside /amd/homelab/root, whenever a user tries to access /net, and symlink /amd/homelab/root to /net/pub. The shared datasets will be made available inside /net/pub.
Now, let's (re)start amd:
$ service amd restart
Stopping amd.
Starting amd.
Nov 4 16:23:39 beastie amd[14853]/info: using configuration file /etc/amd.conf
$ amq
/ root "root"
/media toplvl /etc/amd/media /media
/net toplvl /etc/amd/net /net
Trying to access /net makes amd
mount the shared filesystems:
$ file /net/pub
pub: symbolic link to /amd/homelab/root
$ cd /net/pub/zfs && ls
data/ music/ p2p/ pkg/
$ amq -m | grep homelab
homelab:/net/pub /amd/homelab/root host 0 homelab.retrobsd.ddns.net is up
3. autofs
TODO
Likely covered in a separated post about autofs/automountd.
Also available on my blog at: https://retrobsd.ddns.net/n0bqc3.htm