(On Stock Debian testing aka stretch aka 9, so I have a regular systemd+logind+NetworkManager+GNOME stack)
I have a pair of script that I want to run on startup/shutdown and resume/suspend. This script requires networking to be present when it runs. I have attempt this with the following script:
[Unit] Description=Yamaha Reciever power Requires=network-online.target After=network-online.target Before=sleep.target Conflicts=sleep.target [Service] Type=oneshot ExecStart=/usr/local/bin/av-up ExecStop=/usr/local/bin/av-down RemainAfterExit=yes [Install] WantedBy=graphical.target
This works correctly on startup/shutdown, however during suspend it runs after the network has shutdown and therefore fails.
I have determined that the reason for this is how suspend proceeds under systemd:
- Suspend is initiated by a program (e.g.
systemctl suspend) sending a dbus call to logind.
- Logind then sends a PrepareToShutdown dbus signal to anyone listening.
- Logind then sends a StartUnit dbus call to systemd to run the suspend.target unit.
NetworkManager listens to PrepareToShutdown, so removes the network at (2), while my unit is triggered when systemd actually starts suspending at (3). NetworkManager keeps an "inhibit" lock with logind to ensure it shuts the network down before (3). (Side note: it seems crazy to have something like systemd control ordering of suspend/resume, only to subvert it with logind making stuff circumvent this)
What is the right way to trigger a program to run on suspend/resume while networking is still running?
Should I use NetworkManager pre-down scripts? If so how do I stop it triggering if the network goes down but I'm not suspending?
Is there a way to hook into the suspend process earlier?
Is there a way to make NetworkManager keep the network up longer?
NB: this is distinct from How to write a Systemd unit that will fire before networking goes down as I am talking about suspend/resume.