(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:
systemctl suspend
) en envoyant un appel dbus à logind. 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 .