systemd “Requires=" 옵션 이해

systemd “Requires=" 옵션 이해

에서 systemd.unit(5)이 옵션의 의미는 다음 Requires=과 같습니다.

다른 단위에 대한 요구 사항 종속성을 구성합니다. 이 장치가 활성화되면 여기에 나열된 장치도 활성화됩니다. 다른 장치 중 하나가 비활성화되거나 활성화되지 않으면 이 장치가 비활성화됩니다.

나는 이것에 대해 약간의 실험을했습니다. 나는 2개의 서비스를 만들었 a.service습니다 b.service.

# cat a.service
[Service]
ExecStart=/bin/false

# cat b.service
[Unit]
Requires=a.service

[Service]
ExecStart=/bin/sleep 1000

내가 이 일을 하고 난 후에

systemctl start b.service

실패는 실패 하고 실패는 실패할 것이기 때문에 둘 다 a.service실패 할 것으로 예상합니다 .b.servicea.service/bin/falseb.servicea.service

그러나 b.service실행 중:

root@john-ubuntu:/etc/systemd/system# systemctl status a.service b.service
● a.service
   Loaded: loaded (/etc/systemd/system/a.service; static; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2017-09-07 16:38:39 CST; 2s ago
  Process: 1245 ExecStart=/bin/false (code=exited, status=1/FAILURE)
 Main PID: 1245 (code=exited, status=1/FAILURE)

Sep 07 16:38:39 john-ubuntu systemd[1]: Started a.service.
Sep 07 16:38:39 john-ubuntu systemd[1]: a.service: Main process exited, code=exited, status=1/FAILURE
Sep 07 16:38:39 john-ubuntu systemd[1]: a.service: Unit entered failed state.
Sep 07 16:38:39 john-ubuntu systemd[1]: a.service: Failed with result 'exit-code'.

● b.service
   Loaded: loaded (/etc/systemd/system/b.service; static; vendor preset: enabled)
   Active: active (running) since Thu 2017-09-07 16:38:39 CST; 2s ago
 Main PID: 1244 (sleep)
    Tasks: 1
   Memory: 88.0K
      CPU: 696us
   CGroup: /system.slice/b.service
           └─1244 /bin/sleep 1000

Sep 07 16:38:39 john-ubuntu systemd[1]: Started b.service.

내가 놓친 게 무엇입니까? 감사해요.

답변1

이것은 까다 롭습니다. 이해해야 할 가장 중요한 점은 systemd가 지시하지 않는 한 모든 것을 병렬로 시작한다는 것입니다. 이는 실제로 매뉴얼 페이지의 "요구 사항" 섹션에 명시되어 있습니다.

요구 사항 종속성은 서비스가 시작되거나 중지되는 순서에 영향을 주지 않습니다.

당신이 달성하고 싶은 것은 "a.service가 시작될 때까지 기다리는 것입니다.앞으로b.service"를 시작하십시오. 이를 위해서는 "require"가 필요합니다.그리고b.service 파일의 "이후" 옵션:

[Unit]
Requires=a.service
After=a.service

[Service]
ExecStart=/bin/sleep 1000

=업데이트=

좋아요, 무엇이 잘못되었는지 이해합니다. a.service 파일에 유형을 지정하지 않고 ExecStart 명령을 넣었습니다. 이는 유형이 기본적으로 "단순"으로 설정됨을 의미합니다. 작동하려면 "forked" 유형이 필요합니다. systemd.service 매뉴얼 페이지에서:

simple로 설정하면(Type=이나 BusName=이 지정되지 않았지만 ExecStart=가 지정된 경우 기본값) ExecStart=로 구성된 프로세스가 서비스의 기본 프로세스가 될 것으로 예상됩니다. 이 모드에서 프로세스가 시스템의 다른 프로세스에 기능을 제공하는 경우 해당 통신 채널(예: 소켓 활성화를 통해 systemd에서 설정한 소켓)은 아래와 같이 데몬이 시작되기 전에 설치되어야 합니다.systemd는 즉시 후속 장치 실행을 시작합니다..

분기로 설정된 경우 ExecStart=로 구성된 프로세스는 시작의 일부로 분기()를 호출해야 합니다. 시작이 완료되고 모든 통신 채널이 설정되면 상위 프로세스가 종료될 것으로 예상됩니다. 하위 프로세스는 계속해서 기본 데몬으로 실행됩니다. 이는 전통적인 UNIX 데몬의 동작입니다. 이 설정을 사용하는 경우 systemd가 데몬의 기본 프로세스를 식별할 수 있도록 PIDFile= 옵션도 사용하는 것이 좋습니다. 상위 프로세스가 종료되면 systemd는 계속해서 후속 유닛을 시작합니다.

따라서 "Type=Forking"을 포함하도록 a.service 파일을 업데이트해야 합니다.

[Service]
Type=forking
ExecStart=/bin/false

이것은 작동합니다. :)

답변2

systemd-219(맨 페이지가 질문에서 참조된 부분과 일치함)와 함께 CentOS 7을 사용하는 경우 systemd.unit(5)이는 부분적으로 문서 오류로 인한 것으로 보입니다. 다른 배포판과 시스템 버전에도 동일하게 적용될 수 있습니다.

이 인용문은 댓글에서 인용되었습니다.

다른 장치 중 하나가 비활성화되거나 활성화되지 않으면 이 장치가 비활성화됩니다.

systemctl start b.service이렇게 하면 두 서비스가 모두 활성화되지만 에서 a.service돌아오지 못하면 자동으로 비활성화될 것이라고 제안합니다 . 질문에 이것이 관찰되지 않은 동작이 명시되어 있으므로 CentOS 7에서도 이 동작을 관찰하지 못했습니다./bin/falseb.service

인용된 문장은 다음 문장으로 대체되었습니다.https://www.freedesktop.org/software/systemd/man/systemd.unit.html:

다른 장치 중 하나가 시작되지 않고 실패한 장치의 After= 순서 종속성이 설정된 경우 이 장치는 시작되지 않습니다. 또한 After= 지정 여부에 관계없이 다른 장치 중 하나가 명시적으로 중지되면 이 장치도 중지됩니다.

업데이트된 문서는 After=이를 설정 해야 한다는 @gerard의 설명에 동의 b.service하고 CentOS 7에서 관찰한 동작과 일치합니다.

그런 다음 @gerard가 말했듯이 systemd가 Type=simple서비스를 시작하면 "즉시 후속 장치 시작이 시작됩니다". 이것이 이 문제를 해결하는 데 사용할 수 있는 유일한 설정은 아니며 매뉴얼 페이지 (외에 ) 에 설명된 다른 유형 중 하나를 Type=forking설정할 수도 있습니다 . 테스트의 문제 해결 단계가 완료되면 서비스가 호출하는 것과 같은 주어진 요구 사항에 따라 실제로 실행되고 있는지 확인하십시오 .Type=notifysystemd.service(5)Type=idleTypefork()sd_notify()

또한 systemd-219에는 오류 처리에 대한 많은 극단적인 경우가 있습니다.https://github.com/systemd/systemd/issues/8398

관련 정보