재부팅 시 systemd가 서비스를 중지하는 것을 방지하는 방법

재부팅 시 systemd가 서비스를 중지하는 것을 방지하는 방법

외부 장치를 켜고 끄는 다음 서비스 파일이 있습니다.

[Unit]
Description=Manage the UR controller, turn it off when the system goes down.
Requires=network.target
After=network.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/sbin/ur_boot
ExecStop=/usr/local/sbin/ur_shutdown

[Install]
WantedBy=multi-user.target

잘 작동되는데 외부 장치가 시작하고 종료하는 데 시간이 오래 걸리기 때문에 재부팅하면 다시 준비될 때까지 시간이 걸립니다.

재부팅 시 서비스를 중지하지 않고 예약된 종료를 위해 중지하도록 systemd에 지시할 수 있습니까?

답변1

이 답변은 댓글이 너무 깁니다. 하지만 그것이 당신에게 좋은 방향을 제시해주기를 바랍니다.

에서 man systemd.special:

   shutdown.target
       A special target unit that terminates the services on system shutdown.

       Services that shall be terminated on system shutdown shall add Conflicts= 
       and Before= dependencies to this unit for their service unit, which is 
       implicitly done when DefaultDependencies=yes is set (the default).

모든 서비스에는 암시적으로 Conflicts=가 있습니다 shutdown.target. 따라서 shutdown.target발생하면 모든 서비스가 중지됩니다. 유일한 예외는 추가하는 경우입니다 DefaultDependencies=no.

귀하가 요청한 다른 답변의 의견에서 reboot.target.

   reboot.target
       A special target unit for shutting down and rebooting the system.

세부 사항을 살펴보면 다음과 같은 요인으로 인해 발생함 reboot.target을 알 수 있습니다 .shutdown.targetsystemd1-reboot.service

$ busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/reboot_2etarget
...
.Names    "reboot.target" "runlevel6.target" "ctrl-alt-del.target"
.Requires "systemd-reboot.service"

$ busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/systemd_2dreboot_2eservice
...
.DefaultDependencies false
.After               "final.target" "system.slice" "umount.target" "shutdown.target" "systemd-journald.socket"
.Requires            "final.target" "system.slice" "umount.target" "shutdown.target"
.SuccessAction       "reboot-force"

따라서 귀하의 경우 "재부팅 시 서비스 중지 방지" 섹션 DefaultDependencies=no에 추가할 수 있지만 [Unit]종료 중에 서비스를 중지할 수도 없습니다. 다시 시작하면 종료도 포함되기 때문입니다.


내 최선의 아이디어(가능한지 확실하지 않음)는 서비스를 만드는 것입니다.

[Unit]
DefaultDependencies=no
Before=reboot.target shutdown.target

[Service]
ExecStart=touch %t/rebooting

[Install]
WantedBy=reboot.target

재부팅이 시작되면 RAM에 파일이 생성됩니다.

그런 다음 서비스를 다음으로 변경하십시오.

ExecStop=/bin/bash -c "test -e %t/rebooting || /usr/local/sbin/ur_shutdown"

이렇게 하면 ExecStop파일이 존재하는 동안 명령이 실행되지 않습니다. 이렇게 해도 명령 실행이 차단되지는 않지만 ExecStart주변 장치가 이미 실행 중이면 즉시 반환될 것으로 예상됩니다.

를 실행하지 않으려면 ExecStart비휘발성 위치에 파일을 생성해 보십시오.

ExecStart=touch %S/rebooting

그런 다음 스크립트가 존재하지 않는 경우에만 스크립트를 실행하고 존재하는 경우 정리하십시오.

ExecStart=/bin/bash -c "if [ -e %S/rebooting ]; then rm %S/rebooting; else /usr/local/sbin/ur_start; fi"
ExecStop=/bin/bash -c "test -e %S/rebooting || /usr/local/sbin/ur_shutdown"

답변2

Linux(예: systemd)의 경우 컴퓨터를 종료하거나 다시 시작하는 것 사이에는 차이가 없습니다(한 상태는 컴퓨터가 중지된 상태로 끝나고 다른 상태는 다시 시작된다는 점을 제외하고는 작업이 없다는 점에 유의하는 것이 중요합니다. 이러한 상태에 도달하면 실행 중입니다.) 따라서 재부팅할 때 어떤 것도 계속 실행할 수 없습니다(컴퓨터가 충돌한다는 점을 기억하십시오).

시스템을 중지하고 시스템을 종료되기 전의 상태로 복원하는 기능과 함께 시스템 상태의 복사본(디스크에 메모리 캐싱)을 유지하는 최대 절전 모드와 혼동하지 마십시오.

귀하의 경우 시스템이 부팅하는 데 너무 오랜 시간이 걸리고 부팅을 지연시키는 장치를 식별한 경우 해당 장치에 의존하는 다른 서비스가 무엇인지 확인하고 고려하지 않는 경우 종속성을 제거할 수도 있습니다. important 예, 장치가 부팅될 때 계속 부팅될 수 있도록 합니다.

관련 정보