Wie kann ich meine Benutzerdienste warten lassen, bis das Netzwerk online ist?

14

Ich habe ein paar systemd-Benutzerdienstdateien geschrieben, die Benutzer aktivieren sollen und die eine funktionierende Netzwerkverbindung benötigen. Ich dachte, das wäre so einfach wie:

Wants=network-online.target
After=network-online.target

Die Dienste scheinen jedoch zu früh zu starten, und journalctlich sehe:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

Dann suchte ich weiter und versuchte es

Wants=network.target
After=network.target

und tat sudo systemctl enable systemd-networkd-wait-online.service.

Jetzt habe ich in journalctl:

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.

Und wieder startet der Service zu früh.

Soll diese Botschaft da sein? Wie kann ich mein Problem beheben?


BEARBEITEN : Der Grund ist einfach und speziell im Arch Wiki angegeben :

systemd --userläuft als separater Prozess vom systemd --systemProzess ab. Benutzereinheiten können nicht auf Systemeinheiten verweisen oder von diesen abhängen.

Dieser Forumsbeitrag scheint eine einfache Lösung vorzuschlagen: Ich sollte linkdie nötige Systemeinheit als Benutzer anlegen und somit einen Symlink dazu auf dem Einheitensuchpfad zur Verfügung stellen.

Danach werden keine No such file or directoryNachrichten mehr angezeigt. Ich kann die Dienste jedoch immer noch nicht ausführen, nachdem das Netzwerk online ist. Ich habe versucht network.target, meine Einheiten zu verknüpfen network-online.targetund so systemd-networkd-wait-online.serviceeinzustellen, dass sie von jeder von ihnen abhängen, ohne Erfolg. Wenn ich den Status der verknüpften Einheit im Benutzermodus überprüfe, sind alle tot, z. B .:

$ systemctl --user status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.

Ich kann network-online.targetjedoch im Benutzermodus nach dem Verknüpfen Folgendes sehen:

$ systemctl --user status network-online.target
● network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.
Lev Levitsky
quelle
Ich hoffe du hast eine Antwort.
@Deleteme Danke, ich glaube, ich habe die Ursache dafür gefunden (siehe Update), aber nicht, wie man das Problem löst.
Lev Levitsky
Haben Sie alle eine Lösung für dieses Problem gefunden? Ich bemerke auch, dass Sie betonen, dass nur einige verbundene Einheiten tot sind. Welche haben funktioniert und wie unterscheiden sie sich?
Sparhawk
@Sparhawk leider nicht. Als Workaround verwende ich nur Timer, die nach dem Booten auf einige Sekunden eingestellt sind. Die Frage hat ein Beispiel: Netzwerk-Online-Ziel ist nach der Verknüpfung aktiv und Netzwerk-Ziel ist nicht aktiv.
Lev Levitsky
Vielleicht habe ich ein Missverständnis, aber ich suche nach etwas, das jedes Mal ausgelöst werden kann, wenn das Netzwerk wieder aufgenommen wird, um meine E-Mails nach dem Fortsetzen des Suspend-Vorgangs zu überprüfen. Ich dachte, das wäre der richtige Weg. Ich sehe die Beispiele jetzt. Ich dachte, Sie meinten, einige Zolldienste würden entlassen, andere nicht. Jetzt sprechen Sie jedoch über die Benutzerversionen der Netzwerkziele.
Sparhawk

Antworten:

3

Da Sie sich nicht auf einen Systemdienst verlassen können, besteht Ihre einzige Lösung darin, einen Benutzerdienst bereitzustellen, der erkennt, ob das Netzwerk online ist. (Oder machen Sie Ihre Dienste zu Systemdiensten.) Details für einen "online erkennen" -Benutzerdienst hängen von Ihrer Definition von "online" ab. Es könnte beispielsweise warten, bis ein Ping auf 8.8.8.8 erfolgreich war. Oder für eine erfolgreiche DNS-Namensauflösung. In einer ähnlichen Situation mit vpnc warte ich beispielsweise darauf, dass ein Ping an eine vpn-IP erfolgreich ist.

Dann können Sie Ihre Benutzerdienste von (After =) Ihrem Onlineerkennungsdienst abhängig machen.

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done
Stuart Gathman
quelle
Vielen Dank, das scheint vernünftig und einfach genug. Wenn jedoch 10 Benutzer meinen Benutzerdienst aktivieren, werden 10 Instanzen gleichzeitig denselben Server anpingen, was ein bisschen redundant zu sein scheint. In der Praxis ist dies wahrscheinlich kein Problem, aber ich habe dies in der Hoffnung gefordert, allen Benutzerdiensten eine einzige "Online-Flagge" zur Verfügung zu stellen. Es wurden jedoch noch keine besseren Lösungen vorgeschlagen.
Lev Levitsky
1

Ich würde empfehlen, so etwas zu testen:

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target

Gefolgt von:

# systemctl daemon-reload && systemctl enable foo.service
Marius Karnauskas
quelle
4
Dies ist jedoch ein Systemdienst, und ich versuche, einen Benutzerdienst einzurichten.
Lev Levitsky