네트워크가 온라인 상태가 될 때까지 사용자 서비스를 기다리게 하려면 어떻게 해야 합니까?

네트워크가 온라인 상태가 될 때까지 사용자 서비스를 기다리게 하려면 어떻게 해야 합니까?

나는 사용자가 작동하는 네트워크 연결을 활성화하고 요구하도록 하는 여러 시스템 사용자 서비스 파일을 작성했습니다. 나는 이것이 간단하다고 생각합니다.

Wants=network-online.target
After=network-online.target

그러나 journalctl제 생각에는 이러한 서비스가 너무 일찍 시작되는 것 같습니다.

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

그런 다음 좀 더 검색하고 시도했습니다.

Wants=network.target
After=network.target

그리고 해냈습니다 sudo systemctl enable systemd-networkd-wait-online.service.

지금 나 한테있어 journalctl:

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.

그리고 서비스가 너무 일찍 시작됐어요.

그 메시지가 거기에 있어야합니까? 내 문제를 어떻게 디버깅할 수 있나요?


편집하다: 이유는 아주 간단합니다.아치스 위키:

systemd --user별도의 프로세스로 systemd --system실행됩니다 . 사용자 단위는 시스템 단위를 참조하거나 의존할 수 없습니다.

이 포럼 게시물간단한 해결책이 제안된 것 같습니다. link사용자로서 필요한 시스템 유닛을 제공하여 유닛 검색 경로에 사용 가능한 심볼릭 링크를 생성해야 합니다.

이 작업을 수행한 후에는 어떤 메시지도 표시되지 않았지만 No such file or directory네트워크가 온라인 상태가 된 후에도 서비스가 실제로 실행되도록 할 수 없었습니다. 나는 연결을 시도했고 내 network.target장치 가 성공하지 못한 채 각각에 의존하도록 설정했습니다. 사용자 모드에서 연결된 장치의 상태를 확인할 때 일부는 작동하지 않습니다. 예를 들면 다음과 같습니다.network-online.targetsystemd-networkd-wait-online.service

$ systemctl --user status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.

network-online.target그러나 연결한 후에는 사용자 모드에서 활성 상태를 볼 수 있습니다.

$ systemctl --user status network-online.target
● network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.

답변1

이 주제는 Google 검색 결과에서 1위를 차지하므로 동일한 문제에 직면한 모든 사람을 위해 대체 솔루션을 공유하고 있습니다.

/lib/systemd/system/systemd-networkd-wait-online.service내 시스템에서는 단순화된 상응 항목 (예: ) 을 추가 WantedBy=network-online.target하고 이를 사용자 서비스 디렉터리에 저장했습니다.

[Unit]
Description=User Wait for Network to be Configured

[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-networkd-wait-online
RemainAfterExit=yes

[Install]
WantedBy=default.target

그런 다음 내 사용자 서비스가 이 새로운 서비스에 의존하도록 만들었습니다.

Wants=networkd-wait-online.service
After=networkd-wait-online.service

꼭 필요한 것 같지는 않지만 삭제할 수 있기 Wants=때문에 선택 사항 이 되지만 반드시 필요합니다 .WantedBy=default.targetWantedBy=default.targetnetwork-wait-online.serviceWants=network-wait-online.service

원래 서비스 systemd-networkd-wait-online.service에는 더 많은 종속성이 포함되어 있지만 사용자 컨텍스트에서는 작동하지 않는 것 같습니다. 누군가는 여기에서 systemctl --user linkfor network.targetnetwork-online.target다른 제안을 사용하여 이러한 모든 종속성에 대해 사용자 실행에 상응하는 것을 제공할 수 있지만 저는 간단하게 유지하기로 결정했습니다.

시스템 서비스에 대한 심볼릭 링크를 생성하더라도아니요systemd --user관리자의 일부 이벤트를 사용하여 시스템 서비스 상태를 모니터링 하되 systemd --system사용자 컨텍스트에서 다른 서비스 인스턴스를 실행하도록 관리자에게 지시합니다 .

답변2

시스템 서비스에 의존할 수 없기 때문에 유일한 해결책은 네트워크가 온라인인지 여부를 감지하는 사용자 서비스를 제공하는 것입니다. (또는 서비스를 시스템 서비스로 만드십시오.) "온라인 감지" 사용자 서비스의 세부 사항은 "온라인" 정의에 따라 달라집니다. 예를 들어 ping 8.8.8.8이 성공할 때까지 기다릴 수 있습니다. 또는 성공하려면 DNS 이름 확인을 활성화하세요. 예를 들어 vpnc와 비슷한 상황에서 VPN IP에 대한 ping이 성공할 때까지 기다립니다.

그런 다음 사용자 서비스가 계측된 온라인 사용자 서비스에 종속되도록(After=) 만들 수 있습니다.

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done

답변3

다음과 같이 테스트하는 것이 좋습니다.

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target

다음은:

# systemctl daemon-reload && systemctl enable foo.service

관련 정보