#975873 Please hook zfs-share up to nfs-kernel-server stop+start

#975873#5
Date:
2020-11-26 03:06:15 UTC
From:
To:
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! :-(

#975873#10
Date:
2020-11-26 03:15:23 UTC
From:
To:
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

#975873#13
Date:
2021-01-09 08:46:15 UTC
From:
To:
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

#975873#18
Date:
2021-01-09 09:01:27 UTC
From:
To:
[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

#975873#23
Date:
2021-01-09 09:24:44 UTC
From:
To:
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

#975873#26
Date:
2021-01-09 09:25:34 UTC
From:
To:
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

#975873#31
Date:
2021-01-09 09:39:38 UTC
From:
To:
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?

#975873#34
Date:
2021-01-09 11:32:19 UTC
From:
To:
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

#975873#37
Date:
2021-01-09 11:41:05 UTC
From:
To:
This appears to be fixed as well by adding

    WantedBy=nfs-server.service

in zfs-share.service

Kind regards,
Andrei

#975873#42
Date:
2021-01-09 14:15:17 UTC
From:
To:
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.

#975873#47
Date:
2021-01-10 07:25:56 UTC
From:
To:
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)

#975873#55
Date:
2021-01-10 08:51:36 UTC
From:
To:
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