systemd가 듀얼 포크 데몬을 처리할 수 있나요?
나는 전에 그것을 사용했다초기화.d/데몬을 관리하기 위해 작성한 스크립트는 수년 동안 완벽하게 작동해 왔습니다. 이제 나는체계/스크립트를 실행했지만 데몬 설정 코드를 실행하는 방식으로 작동하도록 할 수 없습니다.
데몬을 설정할 때 제어 터미널을 해제하고 세션 리더가 되는 것을 방지하기 위해 두 번 포크합니다.
문제는 당신이 그렇게 할 때 내가 확인했다는 것입니다체계/추적을 잃고 데몬을 죽입니다. 또한 두 번째 포크를 건너뛰면 다시 작동한다는 것도 확인했습니다.체계/.
내 기본(토론 목적으로 약간 단순화된) systemd/script는 다음과 같습니다.
[Unit]
Description=GM7 Service Daemon
[Service]
Type=forking
ExecStart=/usr/bin/g7ctrl
[Install]
WantedBy=multi-user.target
그래서 내 질문은 다음과 같습니다. 지난 10년 동안 C/C++에서 데몬 설정 코드가 수행된 방식을 변경해야 합니까, 아니면 시스템화/추적 이중 포크를 갖는 옵션이 있습니까?
아직 내부 작동 방식을 완전히 이해하지 못했습니다. systemd 자체가 시작되는 모든 데몬에 대해 프로세스를 생성하는 경우 이중 포크는 실제로 쓸모 없게 됩니다.
나는 내가 한 방식(이중 교차)이 부분적으로 역사적인 이유 때문이라는 점을 인정합니다. 하지만 당시 모범 사례에 대해 꽤 깊이 있게 읽었고 이것이 나중에(약 10년 전) 생각해낸 것입니다.
답변1
지난 10년 동안 C/C++에서 데몬 설정 코드가 수행된 방식을 변경해야 합니까?
예.
약 10년 전만 해도 이는 올바른 접근 방식이 아니었습니다. 1990년대 초반부터 AIX 시스템 리소스 컨트롤러에 문제가 있었습니다. daemontools 사용자들은 1990년대 후반부터 이에 반대해 왔습니다. 2006년에 주류 Linux 운영 체제에 채택된 Upstart에는 적합하지 않습니다. inittab
1980년대 초반 AT&T System 5 Release 3을 실행하는 데는 적합하지 않습니다 .
systemd에는 적합하지 않습니다. 사람들이 이 유형에 대해 말할 수도 있지만 forking
종종 그것이 유형이라는 사실을 잊어버리거나 심지어는 알지도 못합니다.특정한특정 방식으로 완료되는 이중 포크에 따른 서비스 준비 프로토콜. 더 나쁜 것은 프로토콜을 올바르게 표현하는 데 필요한 방식이 여러분과 다른 사람들이 C/C++ 프로그램을 작성하는 방식과 잘 맞지 않는다는 것입니다.
이 주제에 대한 나의 공통된 대답은 2008년에 약 4분의 3 정도 동안 지속되었으며 나와 다른 사람들은 FGA 형식으로 작성하기 전에 오랫동안 사람들에게 같은 내용을 말해 왔습니다.
IBM은 1995년부터 Redbook에서 이 내용을 언급했습니다.
시스템 관점에서 새로운 사람이 시스템 매뉴얼에서 같은 말을 했는데, 겨우 8년 정도 됐어요. ☺
서비스 관리 하위 시스템이 모든 것을 처리하게 하세요. 귀하의 프로그램은이미실행이 시작되면 데몬 컨텍스트에서 실행됩니다.
데몬 오류에 의존하는 모든 코드를 정말로 보존하고 싶다면 적어도 지난 20년 동안 다른 많은 사람들이 했던 일을 하고(일부 daemontools 사람들에 대한 대응으로) 세상에 명령을 내리십시오 - 행 옵션모두 꺼 줘. 하지만 이 명령줄 옵션이 디버그 스위치 역할을 하도록 두지 마십시오.
추가 읽기
- 조나단 드보인 폴라드(2001). Unix 데몬을 설계할 때 피해야 할 실수. 자주 주어지는 답변입니다.
- 조나단 데보인 폴라드(2015).실제로 데몬이 필요하지 않습니다. 진짜.. 체계화된 공포의 집.
- 조나단 데보인 폴라드(2015).Unix 데몬의 준비 프로토콜 문제. 일반적인 답변.
- https://unix.stackexchange.com/a/401611/5132
답변2
예, systemd가 그것을 사용하고 있습니다 Type=forking
.
메인 프로세스가 종료될 때 하나의 프로세스가 남아 있는 한 systemd는 이를 메인 프로세스로 간주합니다.
바라보다전통적인 포크 서비스의 예systemd 문서에서 작동 방식에 대한 자세한 내용과 자세한 설명을 알아보세요 Type=forking
.
systemd는 초기 시작 프로세스 종료와 데몬 시작 및 준비에 대해 더 엄격합니다. 그 예에서:
서비스가 성공적으로 종료되고 하나 이상의 프로세스가 남아 있으면
RemainAfterExit=no
서비스가 시작된 것으로 간주됩니다 .
따라서 첫 번째 하위 프로세스(systemd는 서비스의 기본 프로세스라고 생각함)를 포크한 직후 시작 프로세스가 종료되고 첫 번째 하위 프로세스가 다시 포크되어 종료되므로 systemd는 서비스가 끝났다고 생각하는 경우가 있을 수 있습니다. 실제로 아직은 아닙니다.
어떤 사람들은 논쟁할 것이다이는 System V init에서도 손상된 동작입니다.:
마찬가지로, 잘못된 동기화는 systemd만큼 sysvinit에도 영향을 미칩니다. 우리는 이 문제를 어느 정도 처리할 것이지만, 이 문제를 해결하는 완전히 안전하고 올바른 유일한 방법은 문제가 있는 프로그램을 복구하는 것입니다.
어쨌든, 제가 드리는 최선의 조언은 systemd에서 실행할 때 이중 분기를 건너뛰라는 것입니다. 당신은해야하지제거하다데몬의 이중 분기 기능은 와 같은 명령줄 옵션을 추가하거나 -f
데몬 -F
코드 --foreground
를 건너뛰고 포그라운드에서 프로그램을 실행하기만 하면 됩니다. 시스템 서비스 파일에서 이 옵션을 사용하십시오.
(어쨌든 이러한 옵션은 디버깅이나 문제 해결을 위해 데몬을 실행할 때도 도움이 됩니다.)
systemd는 Type=forking
이중 포크 데몬과 함께 작동할 수 있지만 궁극적으로는 호환성을 위해서만 존재합니다. 포크하지 않으면 많은 이점이 있으므로(주 프로세스를 추적하기가 더 쉽습니다) 프로그램을 수정할 수 있다면 이것이 가장 좋습니다.