suspend/hibernate and NFS mounts

I have a couple of laptop computers running openSUSE Leap 15.0. I bring them from place to place, but when at home they mount NFS filesystems from my home file server.

These laptops are under NetworkManager control, but I have them set up so that the network is started at boot time and stopped at shutdown. Remote NFS filesystems are properly unmounted when I shutdown the system. No problem there.

However, if I suspend or hibernate the laptop, the NFS filesystems are not unmounted before the system suspends or hibernates (even though the network is stopped). As a result, upon resume/thaw, the system immediately hangs.

I found from the following link that systemd provides hooks before and after suspend/hibernate that I could run scripts: https://bbs.archlinux.org/viewtopic.php?id=146790

So I created a shell script /usr/lib/systemd/system-sleep/nfs with this following content:


#!/bin/sh
#
# Unmount NFS filesystems before suspend/hibernate
#

# Debug output
echo "--------- `date` ---------" >>/tmp/pmlog
echo "$0 being invoked with $1 $2]" >>/tmp/pmlog
/usr/bin/ifconfig >>/tmp/pmlog

if  $2 != "suspend" -a $2 != "hibernate" ]
then
        exit 0
fi

case $1 in
        pre)
                # If there are NFS filesystems mounted, umount them forcibly
                if  -n "`df -t nfs 2>/dev/null`" ]
                then
                       sync
                       umount -alt nfs,nfs4
                fi
                ;;
        post)
                # Do nothing: NFS shares will automatically remount
                # after resume/thaw by the system
                ;;
esac

The script does get run before and after the suspend/hibernate, but my debug output in /tmp/pmlog shows that by the time this script is invoked, the network is already stopped, so the umount command in the script hangs. Here is the output in my /tmp/pmlog:


--------- Wed Oct  2 01:18:33 PDT 2019 ---------
/usr/lib/systemd/system-sleep/nfs being invoked with [pre suspend]
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 646  bytes 38012 (37.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 646  bytes 38012 (37.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

As you can see, the ifconfig command shows that my “eth0” and “wlan0” interfaces are already gone at this stage, only the loopback interface “lo” remains.

Is there another way to make the system unmount NFS filesystems before it stops the network and performs a suspend or hibernate? This method obviously cannot work.

That’s correct. NM listens to systemd announcing suspend and stops networking (actually systemd delays suspend sequence until NM replies that it has finished), while scripts in /usr/lib/systemd/system-sleep run very late, when all actions before suspend have already completed.

Is there another way to make the system unmount NFS filesystems before it stops the network

“It” in this case is NetworkManager. You need to use NetworkManager dispatcher scripts. I assume NM calls pre-down script in this case, although you need to test it.

https://developer.gnome.org/NetworkManager/stable/NetworkManager.html

Thanks @arvidjaar

There is already a script /etc/NetworkManager/dispatcher.d/nfs. A cursory look at it seems like it does what I need. So I created a /etc/NetworkManager/dispatcher.d/pre-down.d directory and symlinked this script in there, and it did the trick! Now NFS is unmounted before the network is stopped, and suspend/hibernate + resume/thaw works great without hanging.