Jak sprawić, by moje usługi użytkowników czekały, aż sieć będzie w trybie online?


15

Napisałem kilka systemowych plików usługi użytkownika, które chcę włączyć dla użytkowników i które potrzebują działającego połączenia sieciowego. Pomyślałem, że to będzie tak proste jak:

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

Usługi wydają się jednak uruchamiać zbyt wcześnie i journalctlwidzę:

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

Potem szukałem więcej i próbowałem

Wants=network.target
After=network.target

i zrobił sudo systemctl enable systemd-networkd-wait-online.service.

Teraz mam w journalctl:

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

I znowu usługa zaczyna się zbyt wcześnie.

Czy ta wiadomość powinna tam być? Jak mogę debugować mój problem?


EDYCJA : przyczyna jest prosta i konkretnie podana na Arch Wiki :

systemd --userdziała jako proces odrębny od systemd --systemprocesu. Jednostki użytkownika nie mogą odwoływać się ani zależeć od jednostek systemowych.

Ten post na forum wydaje się sugerować proste rozwiązanie: powinienem linkjako niezbędną jednostkę systemową jako użytkownik, tworząc w ten sposób dowiązanie symboliczne do niej dostępne na ścieżce wyszukiwania jednostek.

Po wykonaniu tej czynności nie widzę żadnych No such file or directorywiadomości, jednak nadal nie mogę sprawić, by usługi faktycznie działały po tym, jak sieć jest w trybie online. Próbowałem łączenie network.target, network-online.targeta systemd-networkd-wait-online.serviceustawienie moich jednostek zależy od każdego z nich, ale bez powodzenia. Kiedy sprawdzam status połączonej jednostki w trybie użytkownika, wszystkie z nich są martwe, np .:

$ 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.

Widzę jednak network-online.targetaktywny w trybie użytkownika po połączeniu:

$ 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.

Mam nadzieję, że będziesz miał odpowiedź.

@Deleteme Dzięki, myślę, że znalazłem przyczynę tego (patrz aktualizacja), ale nie jak rozwiązać problem.
Lev Levitsky

Czy każdy znalazł rozwiązanie tego problemu? Zauważam też, że podkreślasz, że tylko niektóre powiązane jednostki są martwe. Które działały i jak się różnią?
Sparhawk

@Sparhawk niestety nie. Aby obejść ten problem, korzystam z timerów ustawionych na kilka sekund po uruchomieniu. Pytanie ma przykład: cel połączenia z siecią jest aktywny po połączeniu, a cel sieci nie.
Lev Levitsky,

Być może źle zrozumiałem, ale szukam czegoś do uruchomienia przy każdym wznowieniu sieci, aby sprawdzić pocztę e-mail po wznowieniu zawieszenia. Myślałem, że tak to będzie. Widzę teraz przykłady. Myślałem, że masz na myśli niektóre niestandardowe usługi uruchomione, a niektóre nie. Widzę jednak, że teraz mówisz o wersjach użytkowników docelowych sieci.
Sparhawk

Odpowiedzi:


3

Ponieważ nie można polegać na usłudze systemowej, jedynym rozwiązaniem jest zapewnienie usługi użytkownika, która wykrywa, czy sieć jest w trybie online. (Lub uczyń swoje usługi usługami systemowymi.) Szczegóły usługi użytkownika „wykrywaj online” zależą od twojej definicji „online”. Może na przykład poczekać na wykonanie polecenia ping do wersji 8.8.8.8. Lub, aby rozpoznawanie nazw DNS zakończyło się powodzeniem. Na przykład w podobnej sytuacji z vpnc czekam na ping do adresu IP VPN, aby się powiodło.

Następnie możesz uzależnić swoje usługi użytkownika od (Po =) usługi użytkownika wykrywającej online.

#!/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

Dziękuję, wydaje się to rozsądne i proste. Ale jeśli 10 użytkowników włączy moją usługę użytkownika, będzie 10 instancji pingujących ten sam serwer jednocześnie, co wydaje się nieco zbędne. W praktyce prawdopodobnie nie jest to kwestia, ale prosiłem o to w nadziei, że jedna usługa „online flag” będzie dostępna dla wszystkich usług użytkowników. Jednak nie zaproponowano jeszcze lepszych rozwiązań.
Lev Levitsky

1

Poleciłbym przetestować coś takiego:

# /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

Śledzony przez:

# systemctl daemon-reload && systemctl enable foo.service

5
Ale to usługa systemowa i próbuję skonfigurować usługę użytkownika.
Lev Levitsky,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.