Nie zamieszczaj tutaj normalnie, ale odrywam włosy od tego. Mam skrypt w języku Python, który uruchamia się podczas uruchamiania i jest odpowiedzialny za uruchomienie szeregu innych procesów. Ten skrypt był uruchamiany przy starcie przez sysvinit, ale ostatnio uaktualniłem do Debian Jessie, więc dostosowałem go do uruchamiania przez systemd.
Niestety mam problem, którego nie mogę rozwiązać. Po uruchomieniu skryptu bezpośrednio w powłoce użytkownika uruchamia on poprawnie procesy potomne, a gdy skrypt się kończy, procesy potomne są osierocone i kontynuują działanie.
Po uruchomieniu przez systemd, jeśli proces nadrzędny kończy działanie, wszystkie dzieci również wychodzą (cóż, ekran, który uruchamiają w die i pojawiają się jako Dead ???)
Idealnie powinienem móc zrestartować skrypt nadrzędny bez zabijania wszystkich procesów potomnych, czy jest coś, czego mi brakuje?
Dzięki!
[Unit]
Description=Server commander
After=network.target
[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid
ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Edycja: Prawdopodobnie warto wskazać, że skrypt Pythona jest zasadniczo „kontrolerem” procesów potomnych. Uruchamia i zatrzymuje serwery na ekranach GNU zgodnie z żądaniem serwera centralnego. Zwykle zawsze działa, nie odradza usług i nie wychodzi. Są jednak przypadki, w których chciałbym móc ponownie załadować skrypt bez zabijania procesów potomnych, nawet jeśli oznacza to, że procesy są osierocone do pid 1. W rzeczywistości nie ma znaczenia, czy skrypt Pythona uruchamia procesy jako proces nadrzędny, jeśli jest to w ogóle możliwe.
Lepsze wyjaśnienie, jak to działa:
- Systemd spawn /Server.py
- Server.py rozwidla i zapisuje plik pid dla Systemd
- Server.py następnie spawnuje procesy serwera na ekranie GNU zgodnie z jego instrukcjami
- Server.py nadal działa, aby wykonać wszelkie restarty wymagane od serwera
Podczas uruchamiania bez Systemd Server.py można zrestartować, a uruchomione przez niego ekrany GNU pozostają nienaruszone. Podczas uruchamiania za pomocą Systemd, gdy Server.py zamyka się, zamiast procesów ekranowych osieroconych do pid 1, zostają zabici.
źródło
Server.py
kodu i opisu, jak rozwidlają się uruchomione usługi (jeśli rozwidlają). Jednak ogólnie rzecz biorąc, jest to problem niedopasowania protokołu gotowości .ExecStop=
to nie jest potrzebne. Domyślną akcją systemd przy zatrzymaniu jest zabicie procesów. Możesz zajrzeć do dokumentacjiKillMode=
dyrektywy.simple
lubforking
faktycznie), ostatecznością byłobyType=oneshot
,RemainAfterExit=yes
iKillMode=control-group
.Odpowiedzi:
Udało mi się to naprawić, ustawiając KillMode do przetwarzania zamiast grupy kontrolnej (domyślnie). Dziękuje wszystkim
źródło
Co wskazuje, że robisz to źle. Więcej w tym za chwilę.
To nie jest poprawne zachowanie demona. Jeśli „główny” proces - w tym przypadku dziecko, które rozwidliłeś, ponieważ tak określiłeś
Type=forking
- kończy działanie, systemd uważa, że usługa została dezaktywowana i kończy wszelkie inne nadal działające procesy (w grupie kontrolnej) w celu uporządkowania .Czasami konwersja
rc
skryptów System 5 na systemd nie jest prosta, ponieważ właściwy sposób wykonywania zadań w systemied jest zupełnie inny. Właściwy sposób wykonania (powiedzmy) OpenVPN, OpenStack lub OSSEC HIDS w systemd nie jest taki sam, jak w przypadkurc
skryptu. Fakt, że masz skrypt, który rozwidla, a następnie odradza całą masę procesów wnuków, a następnie wychodzi z oczekiwania, że te wnuki będą nadal działać, oznacza, że popełniacie ten sam rodzaj horroruossec-control
, jakkolwiek, chociaż z dwoma mniejszymi poziomami rozwidlania. Jeśli zauważysz, że piszesz skrypt „główny”, który sprawdza flagi „włącz” i uruchamia procesy potomne dla „włączonych” części twojego systemu, to popełniasz ten sam błąd co horrendousossec-control
.Z systemd nie są potrzebne takie domowe mechanizmy. Jest już menedżerem serwisu. Według /unix//a/200365/5132 właściwym sposobem na obejście tego w systemd nie jest posiadanie jednej usługi, która rodzi jakąś zwariowaną i mylącą próbę posiadania „pod-usług”. Ma to mieć każdy proces potomny jako pełnoprawną usystematyzowaną usługę. Następnie włącza się i wyłącza oraz uruchamia i zatrzymuje różne części systemu za pomocą zwykłych kontrolek systemd. Jak widać w przypadku OSSEC HIDS, prosty szablon usługi obejmuje prawie wszystkie usługi (jeden wyjątek znajduje się na stronie /ubuntu//a/624871/43344 ), umożliwiając wykonywanie takich czynności, jak
systemctl enable [email protected]
włączenie opcjonalnegoagentlessd
usługi, bez jakiejkolwiek potrzeby strasznego mechanizmu „skryptu głównego”, który był potrzebny w Systemie 5rc
.Istnieje wiele przypadków, może nie tak ekstremalnych jak OSSEC HIDS, w których takie przemyślenie jest konieczne. MTS, takie jak exim i sendmail, to dwa takie. Ktoś mógł mieć jeden
rc
skrypt, który uruchamia moduł uruchamiający kolejkę, serwer wysyłania SMTP i serwer przekaźnika SMTP, z kilkoma zmiennymi powłoki ad hoc w pliku konfiguracyjnym, aby kontrolować dokładnie, które są uruchamiane. Ale właściwym sposobem na zrobienie tego w systemie systemd jest posiadanie trzech odpowiednich jednostek usług (z których dwie mają powiązane jednostki gniazd ) i brak ad hoc, tylko zwykłe mechanizmy menedżera usług.źródło
Możesz po prostu uśpić rodzica i poczekać, aż systemd zabije go w chwili zatrzymania.
źródło