ネットワークがオンラインになるまでユーザーサービスを待機させるにはどうすればよいですか?

ネットワークがオンラインになるまでユーザーサービスを待機させるにはどうすればよいですか?

私は、ユーザーが動作するネットワーク接続を有効にして要求するようにするために、いくつかのシステムユーザーサービスファイルを作成しました。私はこれが簡単だと思います。

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 linkfornetwork.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

関連情報