W systemd, jaka jest różnica między After = a Require =?

53

Tworzę systemowy plik .service i potrzebuję pomocy w zrozumieniu różnicy między Requires=i After=. Strona mężczyzna mówi, że Requires=„Konfiguruje zależności wymogu na inne jednostki.” oraz After=„Konfiguruje zależności między jednostkami”. Co za różnica?

TomOnTime
źródło

Odpowiedzi:

43

After=konfiguruje zlecenie serwisowe (wykonaj X tylko po Y), podczas gdy Requires=zależności stanu. Jeśli nie określisz zamówienia, usługa zależna od innej zostanie uruchomiona w tym samym czasie, co ta, od której zależy. Również sposób, w jaki to rozumiem (chociaż nie mogę tego teraz przetestować i nie znalazłem referencji), After=to „luźne sprzężenie”, a usługa z taką instrukcją nadal działałaby, gdyby nazwa wymieniona w After=linii nie była w ogóle się nie uruchomił, ale Require=uniemożliwiłby uruchomienie, jeśli warunek nie zostanie spełniony.

Powołując się na https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Wymaga =

Konfiguruje zależności wymagań od innych jednostek. Jeśli ta jednostka zostanie aktywowana, jednostki wymienione tutaj również zostaną aktywowane. Jeśli jedna z pozostałych jednostek zostanie dezaktywowana lub jej aktywacja się nie powiedzie, jednostka ta zostanie dezaktywowana. Tę opcję można podać więcej niż jeden raz lub w jednej opcji można określić wiele jednostek oddzielonych spacjami, w którym to przypadku zostaną utworzone zależności wymagań dla wszystkich wymienionych nazw. Należy pamiętać, że zależności wymagań nie wpływają na kolejność uruchamiania lub zatrzymywania usług. Należy to skonfigurować niezależnie za pomocą opcji After = lub Before =. Jeśli jednostka foo.service wymaga usługi bar.service skonfigurowanej za pomocą Requ = i nie skonfigurowano żadnego zamówienia za pomocą After = lub Before =, wówczas obie jednostki zostaną uruchomione jednocześnie i bez opóźnień między nimi, jeśli aktywowana zostanie foo.service. Często,

i

Przed =, Po =

Rozdzielona spacjami lista nazw jednostek. Konfiguruje zależności porządkowe między jednostkami. Jeśli jednostka foo.service zawiera ustawienie Before = bar.service i obie jednostki są uruchamiane, uruchomienie bar.service jest opóźnione do momentu uruchomienia foo.service. Zauważ, że to ustawienie jest niezależne i prostopadłe do zależności wymagań skonfigurowanych przez Require =. Powszechnym wzorcem jest umieszczanie nazwy jednostki zarówno w opcjach After =, jak i Require =, w którym to przypadku wymienione jednostki zostaną uruchomione przed jednostką skonfigurowaną z tymi opcjami. Tę opcję można podać więcej niż jeden raz, w którym to przypadku tworzone są zależności porządkowe dla wszystkich wymienionych nazw. After = jest odwrotnością Before =, tzn. Podczas gdy After = zapewnia, że ​​skonfigurowana jednostka zostanie uruchomiona po zakończeniu uruchamiania wymienionej jednostki, Before = zapewnia odwrotność, tj. skonfigurowane urządzenie jest w pełni uruchomione przed uruchomieniem wymienionego urządzenia. Należy zauważyć, że gdy dwie jednostki z zależnością między nimi są wyłączone, stosowana jest odwrotność kolejności uruchamiania. tzn. jeśli jednostka jest skonfigurowana z After = na innej jednostce, pierwsza jest zatrzymywana przed drugą, jeśli obie są wyłączone. Biorąc pod uwagę dwie jednostki z dowolną zależnością między nimi, jeśli jedna jednostka zostanie wyłączona, a druga uruchomiona, zamknięcie jest zarządzane przed uruchomieniem. Nie ma znaczenia, czy zależność porządkowania wynosi After = czy Before =. Nie ma również znaczenia, które z nich zostanie wyłączone, o ile jedno zostanie wyłączone, a drugie uruchomione. Wyłączenie jest zarządzane we wszystkich przypadkach przed uruchomieniem. Jeśli dwie jednostki nie mają zależności między nimi, są one jednocześnie wyłączane lub uruchamiane,

Sven
źródło
7
Czym jest zależność, jeśli nie oświadczenie o zamówieniu? (poważnie ... nie rozumiem różnicy)
TomOnTime
Zobacz moją edycję. Moje rozumienie: After=Xoznaczałoby „Zrób to po X, jeśli X jest zrobione”, natomiast Require=Xoznaczałoby „nie rób tego wcale, jeśli nie możesz wykonać X”.
Sven
Before=Sekcja strony człowiek wydaje się to potwierdzać. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up W moim rozumieniu, porządkowanie nie będzie egzekwowane, jeśli bar.servicei tak nie zostanie uruchomione i foo.servicezacznie się normalnie.
Sven
10

Jedną z głównych różnic jest

  • After sprawdza tylko, czy jednostka jest już aktywowana i nie aktywuje jawnie określonych jednostek.
  • Jednostki wymienione w Requiressą aktywowane razem z jednostką. Jeśli którakolwiek z wymaganych jednostek nie uruchomi się, jednostka nie zostanie aktywowana.

Rozważ, że mam plik jednostkowy test-app.service,

[Unit]
Description=test app
After=network-online.target

Oto, co się stanie, gdy to polecenie zostanie wykonane,

  • Aftersprawdza, czy network-online.target.
  • jeśli się network-online.targetnie uruchomi, zaczeka.
  • test-appuruchamia się dopiero po network-online.targetaktywacji

Gdybym Requireszamiast tego

[Unit]
Description=test app
Requires=network-online.target

Oto, co się stanie, gdy to polecenie zostanie wykonane,

  • network-online.targeti test-appsą aktywowane razem
  • jeśli network-online.targetnie uruchomi się test-app, nie zostanie aktywowany.
Sufiyan Ghori
źródło
2

systemd jest menedżerem zadań. Strona podręcznika nie jest bardzo precyzyjna, jak to działa.

Podczas uruchamiania systemd buduje transakcję składającą się z zadań dla zadania zakotwiczenia (tj. Uruchom zadanie dla default.target). Wszystkie te zależności i relacje określają, w jaki sposób i jakie zadania będą uruchamiane. Zamówienie określa, na jakie zadania będą czekać wszystkie inne zadania. Jednostka default.target znajduje się więc w centrum tego wszystkiego, dlatego podczas włączania jednostek używasz odwrotnej zależności, która poprzez systemctl enable tworzy symboliczne łącze systemu plików oznaczające zależność przekazywania, którą może śledzić system (także dlaczego potrzebujesz symlinks systemu plików w pierwsze miejsce). Podobnie jest, gdy ręcznie uruchamiasz jakąś jednostkę, wtedy ta jednostka jest kotwicą, a transakcja jest obliczana na jej podstawie.

Nie wchodząc w zbyt szczegółowe szczegóły, wyjaśnię, co robi Wymaga = i Po =.

Wymagane = spowoduje, że systemd wyzwoli zadanie początkowe dla wymaganej jednostki, gdy zostanie uruchomione zadanie początkowe (jawnie lub poprzez zależność: nie ma wewnętrznego rozróżnienia). Ma również właściwość wyzwalania zadania zatrzymania, gdy urządzenie zostanie zatrzymane (uwaga: zatrzymane, nie spada samo) lub uruchomione ponownie. Oznacza to, że jeśli jakaś zależność / systemctl powoduje zatrzymanie / ponowne uruchomienie, również zatrzymasz / uruchomisz ponownie. Jeśli jednak upadnie samo z siebie, nie przestaniesz, ponieważ nie było pracy, a zmiana stanu nastąpiła bez udziału systemu. Właśnie tam użyłbyś BindsTo = (podobnie do jednostek urządzeń, które z oczywistych powodów mogą stać się nieaktywne bez udziału systemd).

Teraz zaleca się użycie opcji After =, ponieważ Wymaga samej = jest to rozsądne rozwiązanie: anuluj wymaganie, jeśli zadanie początkowe nie powiedzie się. To anulowanie działa jednak tylko dla zadań wrt, tj. Jeśli druga jednostka nie definiuje kolejności, systemd wyzwala oba równolegle, a jeśli jego zadanie początkowe zakończy się przed zakończeniem się niepowodzeniem, nie zostanie anulowane (w rzeczywistości nie można go anulować) . Użycie opcji Po = oznacza, że ​​inne zadanie czeka aż do zakończenia zadania początkowego wymaganej jednostki, aw zależności od wyniku, jeśli się nie powiedzie, zadanie oczekujące na uruchomienie urządzenia zostanie anulowane z wynikiem zadania JOB_DEPENDENCY (dlaczego używasz żółtego [DEPEND] przy rozruchu w takich przypadkach). Dlatego ten efekt unieważnienia jest nieokreślony bez użycia After =.

Dlatego użycie Wants = without After = jest w porządku, jeśli nie chcesz czekać na uruchomienie drugiej jednostki: ponieważ nie ma tam żadnego unieważnienia, więc nie ma wyścigu. W takim przypadku jest to jedynie mechanizm synchronizacji.

Możesz także włączyć oba podczas rozruchu i nie wymagać od siebie nawzajem, i definiować tylko porządkowanie, w takim przypadku, gdy oba zostaną pobrane w ramach tej samej transakcji, zostaną zamówione (lub jeśli zadanie dla drugiego zostanie uruchomione podczas gdy zadanie dla jednostki, którą chce uruchomić, jest uruchomione, najpierw zaczeka na zakończenie, między transakcjami).

Teraz, jeśli nie ma pracy, zamówienie nie ma wpływu na wspomnianą jednostkę. Zazwyczaj jednak istnieje zadanie, w wyniku użycia zależności takich jak Wymaga = i Chce = lub obie są wciągane na raz i definiują pewne porządkowanie, w którym to przypadku czekają na zadania innej jednostki.

Jonathan Kowalski
źródło