Comment puis-je triggersr une unité systemd en veille avant la mise en réseau?

(En stock Debian testing aka stretch aka 9, donc j'ai une routine systemd + logind + NetworkManager + GNOME stack)

J'ai une paire de script que je veux exécuter au démarrage / arrêt et reprendre / suspendre. Ce script exige que le réseau soit présent lorsqu'il s'exécute. J'ai essayé ceci avec le script suivant:

[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 

Cela fonctionne correctement au démarrage / arrêt, mais pendant la suspension il s'exécute après l'arrêt du réseau et donc échoue.

J'ai déterminé que la raison en est comment la suspension passe sous systemd:

  1. La suspension est lancée par un programme (par systemctl suspend ) en envoyant un appel dbus à logind.
  2. Logind envoie alors un signal dbus PrepareToShutdown à toute personne qui écoute.
  3. Logind envoie alors un appel dbus StartUnit à systemd pour exécuter l'unité suspend.target.

NetworkManager écoute PrepareToShutdown, supprime donc le réseau à (2), tandis que mon unité est déclenchée lorsque systemd commence à suspendre à (3). NetworkManager garde un locking "inhiber" avec logind pour s'assurer qu'il arrête le réseau avant (3). (Note de côté: il semble fou d'avoir quelque chose comme systemd control command de suspendre / reprendre, seulement de le subvertir avec logind faire des choses contourner cela)

Quelle est la bonne façon de triggersr un programme à exécuter sur suspendre / reprendre pendant que le réseau est encore en cours d'exécution?

Dois-je utiliser des scripts pré-down NetworkManager? Si oui, comment puis-je arrêter le triggersment si le réseau tombe en panne mais je ne suspend pas ?

Y a-t-il un moyen d'intégrer le process de suspension plus tôt?

Existe-t-il un moyen de faire en sorte que NetworkManager maintienne le réseau plus longtime?

NB: ceci est distinct de Comment écrire une unité Systemd qui se triggersra avant que le réseau ne s'effondre car je parle de suspendre / reprendre.

Selon la documentation systemd-suspend , ainsi que la page de systemctl suspend active le suspend.target .

systemctl list-dependencies suspend.target --after --all montre que suspend.target appelle systemctl-suspend.service puis sleep.target . Cela signifie que lorsque vous appelez systemctl suspend l'ordre des opérations par défaut sont:

 suspend.target |-systemd-suspend.service |-sleep.target 

Si vous avez placé Before=sleep.target , votre ordre des opérations est probable:

 suspend.target |-systemd-suspend.service |-[custom service] |-sleep.target 

Donc, vous êtes le service fonctionne après que systemd-suspend.service fait sa chose, ce qui est probablement votre problème.


Vous pouvez append à votre file de service pour get les résultats corrects :

Before=systemd-suspend.service

Après avoir appelé systemctl daemon-reload vous devriez pouvoir utiliser les systemctl list-dependencies suspend.target --after --all pour voir apparaître votre service entre suspend.target et systemd-suspend.service . Votre ordre d'opérations final devrait être:

 suspend.target |-[custom service] |-systemd-suspend.service |-sleep.target 

Inspiré par https://unix.stackexchange.com/a/139664/160746, j'ai mis à niveau mes scripts de démarrage / arrêt à un démon complet et l'ai fait écouter pour le signal PrepareToShutdown. C'est une course contre NetworkManager à chaque démarrage / arrêt, mais il semble fonctionner de façon fiable sur mon système.

J'ai téléchargé mon code et l'unité systemd à https://github.com/davidn/av .