시스템 및 프로세스 생성: 기본 프로세스가 종료되면 하위 프로세스가 종료됩니다.

시스템 및 프로세스 생성: 기본 프로세스가 종료되면 하위 프로세스가 종료됩니다.

평소에는 여기에 글을 올리지 않지만 이번 포스팅을 위해 올립니다. 시작 시 분기되고 다른 여러 프로세스의 시작을 담당하는 Python 스크립트가 있습니다. 이 스크립트는 부팅 시 실행되었지만 sysvinit최근 Debian Jessie로 업그레이드하여 systemd.

안타깝게도 해결할 수 없는 문제에 봉착했습니다. 사용자 셸에서 직접 스크립트를 시작하면 해당 하위 프로세스가 올바르게 시작되고, 스크립트가 종료되면 하위 프로세스가 고아가 되어 계속 실행됩니다.

systemd를 통해 시작될 때 상위 프로세스가 종료되면 하위 프로세스도 종료됩니다(음, screen시작된 s는 종료되고 Dead로 표시됩니다).

이상적으로는 모든 하위 프로세스를 종료하지 않고 상위 스크립트를 다시 시작할 수 있어야 합니다. 누락된 것이 있습니까?

감사해요!

[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

편집하다:

Python 스크립트는 본질적으로 하위 프로세스에 대한 "컨트롤러"라는 점을 지적하는 것이 적절할 수 있습니다. screen중앙 서버의 요청에 따라 GNU에서 서버를 시작하고 중지합니다 . 일반적으로 항상 실행되며 서비스를 생성하지 않고 종료됩니다.

그러나 어떤 경우에는 프로세스가 pid 1로 고아가 되었다고 하더라도 하위 프로세스를 종료하지 않고 스크립트를 다시 로드할 수 있기를 원합니다. 실제로 Python 스크립트가 프로세스를 상위 프로세스(가능한 경우)로 시작하는지 여부는 중요하지 않습니다.

작동 방식에 대한 더 나은 설명:

  • systemd생산하다Server.py
  • Server.py포크하고 pid 파일에 씁니다.systemd
  • Server.py그런 다음 지침에 따라 GNU 화면에서 서버 프로세스를 생성합니다.
  • Server.py서버에서 요청한 재시작을 수행하려면 계속 실행하세요.

시작에아니요 systemd, Server.py재부팅할 수 있으며 부팅하는 GNU는 screens영향을 받지 않습니다. 시작을 사용할 때 종료 systemd할 때 Server.pypid 1로 고아가 되는 대신 이러한 화면 프로세스가 종료됩니다.

답변1

KillModeprocess(기본값) 대신 에 설정하여 control-group이 문제를 해결했습니다 . 다들 감사 해요!

답변2

시작 시 분기되고 다른 여러 프로세스의 시작을 담당하는 Python 스크립트가 있습니다.

이는 당신이 뭔가 잘못하고 있음을 나타냅니다. 이에 대해서는 나중에 자세히 설명하겠습니다.

스크립트가 종료되면 하위 프로세스는 고아가 되어 계속 실행됩니다.

이는 올바른 데몬 동작이 아닙니다. "기본" 프로세스(이 경우 지정한 하위 프로세스 Type=forking)가 종료되면 systemd는 서비스가 다운된 것으로 간주하고 아직 실행 중인 다른 프로세스(제어 그룹에서)를 종료하여 정리합니다.

때때로 System 5 스크립트를 systemd로 변환하는 것은 rcsystemd에서 작업을 수행하는 올바른 방법이 매우 다르기 때문에 간단하지 않습니다. 예를 들어 systemd에서 OpenVPN, OpenStack 또는 OSSEC HIDS를 수행하는 올바른 방법은 스크립트를 사용하여 이를 수행하는 것과 다릅니다 rc. 포크하는 스크립트가 있고 전체 손자 프로세스를 생성한 다음 종료하고 해당 손자 프로세스가 계속 실행될 것으로 기대한다는 사실은 개별 ossec-control포크 수준이 두 단계 낮음에도 불구하고 동일한 끔찍한 행위를 저지르고 있음을 시사합니다. "활성화" 플래그를 확인하고 시스템의 "활성화" 부분에 대한 하위 프로세스를 실행하는 "주" 스크립트를 작성하고 있다면 끔찍한 일을 하고 있는 것입니다 ossec-control.

systemd에는 그러한 기본 메커니즘이 필요하지 않습니다. 그것이미서비스 매니저. 모든https://unix.stackexchange.com/a/200365/5132, systemd에서 이 문제를 해결하는 올바른 방법은 하나의 서비스가 이상하고 혼란스러운 "하위 서비스" 시도를 생성하지 않도록 하는 것입니다. 이는 각 하위 프로세스를 그 자체로 완전한 시스템 서비스로 취급합니다. 그런 다음 일반 시스템 컨트롤을 사용하여 시스템의 다양한 부분을 활성화 및 비활성화하고 시작 및 중지합니다. OSSEC HIDS 사례에서 볼 수 있듯이 간단한 템플릿 서비스 단위는 거의 모든 것을 포괄합니다(한 가지 예외는 https://askubuntu.com/a/624871/43344) 서비스를 사용하면 System 5에서 요구하는 끔찍한 "마스터 스크립트" 메커니즘 없이도 선택적 서비스 활성화와 같은 작업을 수행할 수 있습니다.systemctl enable [email protected]agentlessdrc

많은 경우 이러한 재고가 필요하지만 아마도 OSSEC HIDS만큼 극단적이지는 않을 것입니다. exim과 sendmail과 같은 MTS가 그 중 두 가지입니다. rc대기열 실행자, SMTP 제출 데몬, SMTP 릴레이 데몬을 생성하는 스크립트가 있을 수 있으며 , 구성 파일에 있는 임시 셸 변수를 사용하여 실행되는 항목을 정확하게 제어할 수 있습니다. 하지만 systemd를 사용하여 이를 수행하는 올바른 방법은 다음과 같습니다.세 가지 적절한 서비스 단위(두 개가 연결되어 있어요.소켓 유닛) 임시적인 작업은 전혀 없으며 서비스 관리자의 일반적인 메커니즘만 있을 뿐입니다.

답변3

상위 프로세스를 절전 모드로 전환한 다음 systemd가 중지 시간에 해당 프로세스를 종료할 때까지 기다릴 수 있습니다.

관련 정보