네트워크가 종료되기 전에 일시 중지된 시스템 장치를 트리거하는 방법은 무엇입니까?

네트워크가 종료되기 전에 일시 중지된 시스템 장치를 트리거하는 방법은 무엇입니까?

(일명 Stock Debian 테스트에서 9로 늘이기 때문에 일반 systemd+logind+NetworkManager+GNOME 스택이 있습니다)

시작/종료 및 재개/일시 중지 시 실행하려는 스크립트 쌍이 있습니다. 이 스크립트를 실행하려면 네트워크가 있어야 합니다. 다음 스크립트를 사용하여 이 작업을 수행하려고 합니다.

[Unit]
Description=Yamaha Reciever power
Requires=network-online.target
After=network-online.target
Before=sleep.target
Conflicts=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/av-up
ExecStop=/usr/local/bin/av-down
RemainAfterExit=yes

[Install]
WantedBy=graphical.target

시작/종료 시에는 제대로 작동하지만 일시 중지 중에는 실행됩니다.뒤쪽에네트워크가 다운되어 오류가 발생했습니다.

나는 원인이 systemd에서 멈추는 방식이라고 판단했습니다.

  1. systemctl suspend정지는 로그인에 dbus 호출을 보내는 프로그램(예: )에 의해 시작됩니다 .
  2. 그런 다음 Logind는 듣고 있는 사람에게 prepareToShutdown dbus 신호를 보냅니다.
  3. 그런 다음 Logind는 Systemd에 StartUnit dbus 호출을 보내 suspens.target 장치를 실행합니다.

NetworkManager는 prepareToShutdown을 수신하므로 (2)에서 네트워크가 제거되고 systemd가 실제로 (3)에서 중단되기 시작할 때 내 장치가 트리거됩니다. NetworkManager는 로그인 시 "금지된" 잠금을 유지하여 (3) 이전에 네트워크를 종료합니다. (참고: systemd를 사용하여 일시 중지/재개 명령과 같은 것을 제어하고 이를 우회하기 위해 로그인으로 이를 파괴하는 것은 미친 것 같습니다)

네트워크가 계속 실행되는 동안 일시 중지/재개 시 프로그램이 실행되도록 트리거하는 올바른 방법은 무엇입니까?

NetworkManager 사전 종료 스크립트를 사용해야 합니까? 그렇다면 네트워크가 다운되었을 때 트리거되는 것을 방지하려면 어떻게 해야 합니까?아니요정지시키다?

프로세스를 미리 중단할 수 있는 방법이 있나요?

NetworkManager에 네트워크를 더 오래 실행하도록 지시하는 방법이 있습니까?

참고: 이는 다음과 다릅니다.네트워크 중단 전에 트리거되는 Systemd 장치를 작성하는 방법내가 말했듯이 일시 중지 / 재개.

답변1

에서 영감을 받다https://unix.stackexchange.com/a/139664/160746시작/중지 스크립트를 전체 데몬으로 업그레이드하고 prepareToShutdown 신호를 수신하도록 했습니다. NetworkManager를 사용한 모든 시작/중지 경주이지만 내 시스템에서는 안정적으로 작동하는 것 같습니다.

내 코드와 시스템 장치를 다음에 업로드했습니다.https://github.com/davidn/av.

답변2

~에 따르면시스템 정지문서화 및systemctl 매뉴얼 페이지 systemctl suspend활성화 suspend.target.

systemctl list-dependencies suspend.target --after --all명시적으로 then 을 suspend.target호출하세요 . 즉, 전화 할 때systemctl-suspend.servicesleep.targetsystemctl suspend기본작업 순서는 다음과 같습니다.

suspend.target
|-systemd-suspend.service
  |-sleep.target

Before=sleep.target그때 배치하면당신의작업 순서는 다음과 같습니다.

suspend.target
|-systemd-suspend.service
  |-[custom service]
    |-sleep.target

서비스가 실행 중입니다.뒤쪽에 systemd-suspend.service일을 하십시오. 이것이 당신의 문제일 수 있습니다.


서비스 파일에 추가하여 얻을 수 있습니다.올바른 결과:

Before=systemd-suspend.service

전화를 걸면 및 사이에 서비스가 표시되는 것을 볼 systemctl daemon-reload수 있습니다 . 최종 작업 순서는 다음과 같습니다.systemctl list-dependencies suspend.target --after --allsuspend.targetsystemd-suspend.service

suspend.target
|-[custom service]
  |-systemd-suspend.service
    |-sleep.target

답변3

작업 솔루션이 있습니다. 그것은 나에게 최고는 아니지만 다른 사람에게도 최고는 아닙니다. /lib/systemd/system-sleep/tv_on_off에 다음과 같은 내용을 입력하세요.

#!/bin/sh
# should be placed at 
# /lib/systemd/system-sleep

if [ "${1}" = "pre" ]; then
   # about to suspend no network here
   systemctl restart network-manager.service
   nm-online

   # code that requires network
   /usr/local/bin/av-down

elif [ "${1}" = "post" ]; then
   # about to resume 
   systemctl restart network-manager.service
   nm-online

   # code that requires network
   /usr/local/bin/av-up
fi

@David가 언급한 systemd 및 dbus 방법을 시도했습니다. dbus 메시지 처리를 사용하더라도 코드가 실행되기 전에 네트워크가 종료됩니다. 아니면 병렬로.

답변4

에 따르면회신하다systemd-devel 메일링 리스트에서 네트워크 관리자를 사용할 때 systemd를 단독으로 사용하는 것은 불가능합니다. 왜냐하면 네트워크 관리자는 자체적으로 절전 신호를 수신하기 때문입니다. 해결책은 직면해야 하는 상황을 다음과 같이 설정하는 것입니다.

/etc/NetworkManager/dispatcher.d/pre-down.d/

이는 인터페이스가 실패할 때마다 스크립트를 트리거한다는 점에 유의하십시오. 내 컴퓨터에서는 문제가 없지만 귀하의 컴퓨터에서는 그렇지 않을 수도 있습니다. D-Bus 일시정지 신호가 발생하는지 확인할 수 있지만 아직 살펴보지 않았습니다. 이에 대한 티켓이 있습니다네트워크 관리자 gitlab 추적기.

관련 정보