systemd 서비스 내에서 systemd 서비스를 시작하면 교착 상태가 발생합니다.

systemd 서비스 내에서 systemd 서비스를 시작하면 교착 상태가 발생합니다.

first.serviceBash 스크립트를 호출하는 시스템 서비스(라고 부르겠습니다)가 있습니다.

이 bash 스크립트에서는 먼저 중지한 다음 다른 서비스 systemctl(예 systemctl start another.service: .

쉘에서 스크립트를 실행하면 모든 것이 잘 작동하고 another.service중지되었다가 나중에 시작된다는 것을 알았습니다.

systemd를 호출하면 systemctl restart first.service" "이 올바르게 중지되었지만 another.service계속 시작됩니다.

결과를 확인하면 ps두 systemctl 호출, 즉 systemctl restart first.servicesystemctl start another.service.

나는 systemd 230을 사용하고 있습니다

이것이 알려진 동작입니까? 이 문제를 어떻게 해결할 수 있나요?

서비스 내에서 시스템 서비스를 (다시) 시작하는 것을 처리하는 더 좋은 방법이 있습니까?

편집하다:내 first.service파일:

[Unit]
Description=First service
#Before=local-fs.target apache2.service rsyslog.service

[Service]
Type=oneshot
ExecStart=/usr/bin/test.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

another.service파일:

[Unit]
Description=Test service

[Service]
Type=oneshot
ExecStart=/bin/bash -c "while ( true  ) ; do { date ; echo 'It works!' ; sleep 10 ; } done"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

내 bash 스크립트는 다음과 같습니다.

#!/bin/bash
echo stopping
systemctl stop another.service
echo "result of stop = $?"
echo starting
systemctl start another.service
echo "result of start = $?"
echo DONE

매달린 후 다음과 같은 출력을 얻습니다 ps.

[piotr@/etc/systemd/system] $ ps -aux | grep systemctl
root      7801  0.0  0.0  27696  1336 pts/21   S+   16:06   0:00 systemctl restart first
root      7807  0.0  0.0  27696  1320 ?        S    16:06   0:00 systemctl start another.service
piotr     7915  0.0  0.0  15752   968 pts/22   S+   16:06   0:00 grep --color=auto systemctl

편집 2systemctl status:다른 콘솔에서 호출될 때 두 서비스 모두에서 메시지를 게시하고 있습니다 systemctl restart first.

또한 bash 스크립트에서 반환 값 확인을 추가했습니다. 위와 같이 업데이트되었습니다.

first.service:

● first.service - First service
Loaded: loaded (/etc/systemd/system/first.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 46s ago
Main PID: 12761 (test.sh)
CGroup: /system.slice/first.service
├─12761 /bin/bash /usr/bin/test.sh
└─12766 systemctl start another.service

Apr 19 16:34:43 piotr-ideapad systemd[1]: Starting First service...
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: stopping
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: result of stop = 0
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: starting

another.service:

● another.service - Test service
Loaded: loaded (/etc/systemd/system/another.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 1min 40s ago
Main PID: 12767 (bash)
CGroup: /system.slice/another.service
├─12767 /bin/bash -c while ( true   ) ; do { date ; echo 'It works!' ; sleep 10 ;  } done
└─13066 sleep 10

Apr 19 16:35:43 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:43 CEST 2017
Apr 19 16:35:43 piotr-ideapad bash[12767]: It works!
Apr 19 16:35:53 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:53 CEST 2017
Apr 19 16:35:53 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:03 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:03 CEST 2017
Apr 19 16:36:03 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:13 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:13 CEST 2017
Apr 19 16:36:13 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:23 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:23 CEST 2017
Apr 19 16:36:23 piotr-ideapad bash[12767]: It works!

편집 3: 몇 가지 의견을 교환한 후 질문을 다시 표현해 보겠습니다.

위에 나열된 프로세스 중 어느 것도 활성화되거나 시작되지 않았다고 가정합니다. 내가 그들에게 전화하면 systemctl status그들은 loaded단지 inactive.
그런 다음 전화했는데 systemctl start first이 터미널 명령이 완료되지 않았습니다.
이러한 서비스를 호출하면 해당 서비스의 systemctl status상태를 알 수 있지만 터미널에서의 실행은 여전히 ​​종료되지 않고 무기한 정지됩니다.Active:activating (start)systemctl start first

내 생각에는 두 프로세스가 모두 대기열에 있고 systemctl start another내 bash 스크립트에서 자체적으로 완료되기 전에 완료될 때까지 기다리고 있는 것 같습니다 systemctl start first. 여기에 교착 상태가 있습니다.

답변1

교착 상태 지시어로 보이는 것은 Type=oneshot실제로는 광고한 대로 작동합니다. 다음 명령을 직접 실행하면 "중지"가 트리거될 수 있습니다 another.service.

systemctl start another

취소되면 journalctl전혀 "중지"되지 않고 예상대로 무한 루프가 실행되는 것을 확인할 수 있습니다. man systemd.service다음 문서를 찾을 수 있습니다 Type=oneshot.

oneshot은 단순하게 동작하지만 systemd가 후속 유닛을 시작하기 전에 프로세스가 종료되어야 합니다.

즉, 무한 루프를 작성한 다음 계속하기 전에 완료될 때까지 기다리도록 systemd에 지시합니다.

Type=와 같은 다른 것을 사용하거나 Type=simple기본 프로세스의 무한 루프 종료를 사용해야 합니다.

관련 정보