- Package:
- zfsutils-linux
- Source:
- zfs-linux
- Submitter:
- "Trent W. Buck"
- Date:
- 2021-01-10 08:54:02 UTC
- Severity:
- minor
I'm not sure who is 'at fault' here, or where the fix belongs.
The problem I ran into was this:
1. I zfs set sharenfs (not /etc/exports), because
it makes config management a little easier (exports(5) lacks a "drop-in" dir).
2. During an apt update, needrestart asks to restart NFS.
3. I tell needrestart "sure, go ahead".
4. All my NFS exports are gone!
I can reproduce the symptoms with stop+start, but not restart:
root@odin:~# exportfs -s
/srv/old-disks goll.lan(ro,async,wdelay,root_squash,no_subtree_check,mountpoint,sec=sys,ro,secure,root_squash,no_all_squash)
root@odin:~# systemctl restart nfs-kernel-server
root@odin:~# exportfs -s
/srv/old-disks goll.lan(ro,async,wdelay,root_squash,no_subtree_check,mountpoint,sec=sys,ro,secure,root_squash,no_all_squash)
root@odin:~# systemctl stop nfs-kernel-server
root@odin:~# systemctl start nfs-kernel-server
root@odin:~# exportfs -s
[UH OH, PROBLEM!]
root@odin:~# zfs share -a
root@odin:~# exportfs -s
/srv/old-disks goll.lan(ro,async,wdelay,root_squash,no_subtree_check,mountpoint,sec=sys,ro,secure,root_squash,no_all_squash)
Can ZFS hook NFS, or vice-versa, so this problem flow stops happening?
This has already bitten me twice! :-(
This quick-and-dirty fix seems to work for me:
root@odin:~# systemctl cat nfs-kernel-server
# /lib/systemd/system/nfs-server.service
[...]
# /etc/systemd/system/nfs-server.service.d/zfsutils-linux.conf
# If you configure NFS exports in "zfs set sharenfs",
# this will remove all your NFS shares!
#
# systemctl stop nfs-kernel-server
# systemctl start nfs-kernel-server
#
# This is an attempt at a quick fix.
[Service]
ExecStartPost=/sbin/zfs share -a
I can reproduce this as well. If my understanding of systemd.unit(5) is correct this works as expected when using the PartOf= directive: zfs-share is stopped or restarted together with nfs-service, but not started. Maybe the needrestart Maintainers have a better idea what is going on here? (adding to Cc: and attaching zfs-share.service for their convenience) Kind regards, Andrei
[really Cc'ing needrestart maintainers, sorry for duplicates] I can reproduce this as well. If my understanding of systemd.unit(5) is correct this works as expected when using the PartOf= directive: zfs-share is stopped or restarted together with nfs-service, but not started. Maybe the needrestart Maintainers have a better idea what is going on here? (adding to Cc: and attaching zfs-share.service for their convenience) Kind regards, Andrei
Am 09.01.21 um 09:46 schrieb Andrei POPESCU: Right, PartOf= works as documented. Can you elaborate why zfs-share.service uses PartOf=nfs-kernel-server.service ? I never used ZFS, so I basically have zero knowledge how it is supposed to work. Regards, Michael
BTW, /etc/exports.d/ is supported for quite some time, see e.g. #676604. Unfortunately it seems that configuring any exports there (e.g. non-ZFS filesystems) disables all ZFS "native" exports. Kind regards, Andrei
Hm, I assume this triggers the mount of ZFS volumes. While I understand the motivation for the stop+start nfs-server.service case, what happens during boot? Does this have the potential to trigger the mount at a time when not all dependencies are ready?
At first I thought this is a problem with the PartOf directive, but then I noticed the man page explicitly mentions restart and stop only, but not start. Probably, e.g. in case nfs-server is started before the ZFS pool is ready. Additionally zfsutils-linux is in contrib, so even if it does work reliably it's likely unsuitable to apply such a fix to the nfs-kernel-server package. In my limited testing a WantedBy=nfs-server.service seems to do the trick (somehow I was under the impression this can be used only with targets). Still curious why a stop/start is triggered by needrestart though. Kind regards, Andrei
This appears to be fixed as well by adding
WantedBy=nfs-server.service
in zfs-share.service
Kind regards,
Andrei
Am 09.01.21 um 12:32 schrieb Andrei POPESCU: You could ship a drop-in snippet in zfsutils-linux extending the nfs-kernel-server service. Targets are typically used to group together services and to generalise things. But WantedBy=nfs-server.service is perfectly valid. It has the downside to be tied to the nfs-server.service name. That, and why needrestart uses stop/start instead of restart.
Michael Biebl wrote:
Here is a rough summary, I hope this helps!
ZFS glossary:
* a "vdev" is an underlying physical disks/partitions (e.g. /dev/sda)
* a "pool" is made of 1 or more vdevs (e.g. "morpheus")
* a "dataset" is a logical volume/filesystem inside the pool (e.g. "morpheus/home/alice")
* a "zvol" or "volume" is a dataset that stores blocks (used for e.g. VMs)
* a "zfs" or "filesystem" is a dataset that stores files
* a "property" is a key/value pair associated with a dataset (e.g. "compression=lz4").
NFS integration background:
* ZFS properties can (optionally) replace /etc/fstab, /etc/exports, /etc/smb.conf.
* If you do
zfs set mountpoint=/home morpheus/home
zfs set sharenfs=on morpheus/home
that is roughly like
morpheus/home /home zfs defaults # in fstab
/home *(rw) # in exports
* USUALLY that is all you need.
ZFS calls mount/umount/exportfs/... automatically when appropriate,
so the running system matches the ZFS properties.
* You can call "zfs unshare" to manually stop NFS/SMB shares configured via ZFS properties.
* You can call "zfs share" to manually start NFS/SMB shares configured via ZFS properties.
Postscript:
* Properties are recursive, so if you have ZFS datasets like
morpheus/home
morpheus/home/alice
morpheus/home/bob
If you "zfs set sharenfs=on morpheus/home", alice & bob are implicitly also shared.
For NFS, this means things Just Work without needing no_subtree_check or a lot of repetition in /etc/exports.
* The sharenfs= property can be more complicated than "on".
The notation follows Solaris, not Linux.
For example,
zfs set sharenfs=sec=sys,ro,rw=example.com,rw=example.net,all_squash morpheus/home
means something like
/home *(ro,sec=sys,all_squash)
/home example.com(rw,sec=sys,all_squash)
/home example.net(rw,sec=sys,all_squash)
Trent W. Buck wrote: linux nfs hooks: https://github.com/openzfs/zfs/blob/master/lib/libshare/os/linux/nfs.c https://github.com/openzfs/zfs/blob/master/cmd/zfs/zfs_main.c#L235 NFS-related manpages: https://github.com/openzfs/zfs/blob/master/man/man8/zfs-share.8 https://github.com/openzfs/zfs/blob/master/man/man8/zfsprops.8#L1582 overview manpages: https://github.com/openzfs/zfs/blob/master/man/man8/zfsconcepts.8 https://github.com/openzfs/zfs/blob/master/man/man8/zpoolconcepts.8 NOTE: in zfs 0.8, there were 2 great big manpages. in zfs 2.0, there are lots of little manpages.
As far as I understand ZFS needs NFS to be up and running before being able share any of its file systems via NFS. Since I'm new to ZFS myself and my experience with NFS is also limited I'll let the package Maintainer elaborate on that. Kind regards, Andrei