Linux (systemd, NetworkManager): how to run a script on suspend before networking is shut down

By | February 24, 2023

I recently found myself faced with the problem described in this Stack Exchange question, specifically, how can I get a script to run immediately before my laptop suspends, but while the network is still running?

There is actually a way to run a script before suspend: you put it in the directory /usr/lib/systemd/system-sleep, and systemd runs it before the computer is suspended. But unfortunately by the time that happens NetworkManager has already started to disable the network, so the script can’t use networking.

When I discovered the problem while trying to figure this out, I did some internet searching to see if anyone else had encountered the same problem and come up with a solution, which is how I found the question on Stack Exchange. That brought me to another possible solution mentioned in one of the answers there: if you put a script in /etc/NetworkManager/dispatcher.d/pre-down.d, then NetworkManager will run it before shutting down any network connection. That sounded like it would do what I needed, so I tried it out, and it worked as advertised… but only on one of my two laptops. On the other one, the scripts in pre-down.d weren’t being called on suspend.

This led to some pulling out of hair while I tried to figure out why one laptop was behaving differently from another, and fortunately I was able to figure it out: I had wake-on-wlan enabled for my home wifi connection on one laptop, and for some reason (I think it’s a bug), when wake-on-wlan is enabled the scripts in pre-down.d don’t get called on suspend.

I thought I was at another dead end, but then I discovered something very interesting: it appears that when wake-on-wlan is enabled, at the point where the scripts in system-sleep are called the network is reliably still working!

My solution, then, was two-fold: I put a copy of my script in the pre-down.d directory for NetworkManager to run it from there when wake-on-wlan is disabled, and I put another copy of the same script in the system-sleep directory, for systemd to run it from there when wake-on-wlan is enabled.

Note that when wake-on-wlan is disabled, both copies of the script get called, but the one called from system-sleep fails because the network is down; I’ve written my script to be resilient to this.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *