私はsystemdに比較的慣れておらず、そのアーキテクチャを学んでいます。
現在、カスタムシェルスクリプトを実行する方法を理解しようとしています。このスクリプトは実行する必要があります後ネットワーク層が起動しました。
私はsystemctlとnetctlを使用してArchを実行しています。
テストするために、ip addr list > /tmp/ip.txt
を実行するだけの簡単なスクリプトを作成しました。このスクリプト用に次のサービスファイルを作成しました。
(/etc/systemd/system/test.service)
[Unit]
Description=test service
[Service]
ExecStart=/root/test.script
[Install]
WantedBy=multi-user.target
次に、スクリプトを有効にしました。
systemctl enable test
再起動すると、スクリプトは実際に実行されますが、ネットワークが開始される前に実行されます。つまり、ip.txt
の出力には、プライマリインターフェイスに割り当てられているIPv4アドレスは表示されません。ログインするまでに、IPv4アドレスが割り当てられ、ネットワークが稼働しています。
WantedBy
パラメーターをいじることでスクリプトの実行ポイントを変更できると思いますが、その方法はわかりません。
誰かが私を正しい方向に向けることができますか?
Systemdのユニットの順序に影響を与えることは非常に簡単です。一方、完成したユニットが何を保証するかについて注意する必要があります。
現在のシステムでは、network.target
の後に注文しても、ネットワークサービスが開始されていることが保証されるだけであり、実際の構成があることは保証されません。あなたはnetwork-online.target
の後に注文し、それを実現するためにそれを引き込む必要があります。
[Unit]
Wants=network-online.target
After=network-online.target
古いシステムとの互換性のために、network.targetの後に注文する必要がある場合もあります。
[Unit]
Wants=network-online.target
After=network.target network-online.target
それはあなたのサービスのユニットファイルとsystemdのためです。
次に、network-online.target
が期待どおりに機能することを確認する必要があります(または、少なくともnetwork.target
を使用できることを確認してください)。
NetworkManagerの現在のバージョンはNetworkManager-wait-online.service
を提供しており、これはnetwork-online.target
によって、つまりサービスによって取得されます。この特別なサービスにより、サービスは、開始するように構成されたすべての接続が自動的に成功、失敗、またはタイムアウトするまで待機します。
現在のバージョンのsystemd-networkdは、すべてのデバイスが要求どおりに構成されるまでサービスをブロックします。現在のところ、起動時に適用される構成(より具体的には、 `systemd-networkd.serviceの起動時)のみをサポートしているため、より簡単です。
完全を期すために、Fedoraの/etc/init.d/network
サービスは、systemdの現在のバージョンによって解釈されるように、network.target
をブロックし、したがってnetwork-online.target
とサービスを間接的にブロックします。これは、スクリプトベースの実装の例です。
デーモンベースかスクリプトベースかに関係なく、実装が上記のネットワーク管理サービスの1つとして動作する場合、ネットワーク構成が正常に完了するか、正当な理由で失敗するか、妥当な時間後にタイムアウトになるまで、サービスの開始を遅らせます完了するフレーム。
netctlが同じように機能するかどうかを確認することをお勧めします。その情報は、この回答への貴重な追加となります。
これがうまく機能しないsystemdの十分に古いバージョンが表示されるとは思いません。ただし、少なくともnetwork-online.target
が存在し、network.target
の後に注文されていることを確認できます。
以前はNetworkManagerは、少なくとも1つの接続が適用されることが保証されていました。そして、それが機能するためにも、NetworkManager-wait-online.service
を明示的に有効にする必要があります。これはFedoraで長い間修正されましたが、最近アップストリームに適用されました。
systemctl enable NetworkManager-wait-online.service
ソフトウェアをNetworkManager.service
またはNetworkManager-wait-online.service
やその他の特定のサービスに依存させる必要はありません。代わりに、すべてのネットワーク管理サービスはnetwork.target
の前、およびオプションでnetwork-online.target
の前に自分自身を注文する必要があります。
単純なスクリプトベースのネットワーク管理サービスは、終了する前にネットワーク構成を完了し、network.target
の前に、したがってnetwork-online.target
の前に間接的にそれ自体を注文する必要があります。
[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
デーモンベースのネットワーク管理サービスも、あまり便利ではありませんが、network.target
の前にそれ自体を注文する必要があります。
[Unit]
Before=network.target
[Service]
Type=simple
ExecStart=...
デーモンが完了するのを待つサービスは、特定のサービスの後、network-online.target
の前に自分自身を注文する必要があります。デーモンサービスでRequisite
を使用して、それぞれのネットワーク管理サービスが使用されていない場合にすぐに失敗するようにする必要があります。
[Unit]
Requisite=...
After=...
Before=network-online.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
パッケージは、network-online.target
のwants
ディレクトリにある待機中のサービスへのシンボリックリンクをインストールして、構成されたネットワークを待機するサービスによって取得されるようにする必要があります。
ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/
あなたが質問したときにあなたの質問に答えるのを助けただけでなく、アップストリームとLinuxディストリビューションの状況の改善にも貢献して、元の質問を書いたときよりも良い答えを出せるようになれば幸いです。 。
[Unit]
セクションのAfter
を使用して、サービスを開始する前に開始する必要があるサービスを定義できます。たとえば、NetworkManagerを使用している場合、NetworkManagerの起動後にサービスを開始できます。
[Unit]
Description=test service
After=NetworkManager.service
サービスがサーバーを提供していて、誰かがサーバーに接続するのを受動的に待機できる場合は、これを使用します。
[Unit]
After=network.target
サービスはワイルドカードインターフェイスにバインドする必要があります。ソケットのアクティブ化を使用する場合(推奨)、またはローカルのみである場合は、ネットワークターゲットを完全に無視できます。
サービスがクライアントとして機能する場合、またはピアツーピアの場合、これはより適切です。
[Unit]
After=network-online.target
Requires=network-online.target
systemd 21 の前に、network-online.targetはPavelが述べた回避策が必要です(ネットワークが起動するのを待つサービスを手動で有効にする必要があります)。 systemd 213以降、これはデフォルトで行われます。 systemd-networkd-wait-online
は、非ループバックインターフェイスで少なくとも1つのアドレス(ルーティング可能またはリンクローカル)が構成されるのを待ちます。
Systemd-networkd、NetworkManager、または同等の設定は、独立したタスクです。 DHCP(IPv4の場合)とNDP(IPv6の場合)はそのまま使用できる傾向がありますが、「ネットワークが稼働している」という正確な定義がトリガーとなるように構成する必要がありますnetwork-online.target
。
ドキュメンテーション:
WantedByパラメータをいじることで、スクリプトが実行されるポイントを変更できると思います
それはあなたが望むものとは逆の効果があります。 man systemd.unit
から:
WantedBy =、RequiredBy =
[...]このユニットがsystemctl enableによってインストールされると、リストされた各ユニットの.wants /または.requires /ディレクトリにシンボリックリンクが作成されます。これには、タイプWants =またはRequires =の依存関係がリストされている単位から現在の単位に追加されるという効果があります。
これに基づいて、適切な単位オプションは「Wants」または「Requires」であることがわかります。それらの説明に基づいて、「必要」はおそらく正しいです。「後」を追加して、ネットワークサービスが実行されるだけでなく、このユニットの前に実行されるようにします。
ユニットオプションのAFAIKには、開始された前提条件が完了している必要がある、または特定のポイントに到達している必要があるという条件(ネットワークはおそらくデーモンサービスである)を含めることはできませんstart最初。これを念頭に置いて、スクリプトをType=forking
にして、正常な遅延(たとえば30秒)、または遅延を含む何らかの成功時の終了ループを投入して、最初にDHCPリース。
[Unit]
セクションのAfter
を使用して、独自のサービスの前に何を開始するかを指定します。 (これまでの答えのこれは正しいです。)
ネットワークが稼働した後でサービスを開始するには、NetworkTargetを使用します。NetworkTargetは、NetworkManager、Archのconf.d/netctlシステム、またはsystemdが認識している他のサービスを使用するかどうかに適用されます。
[Unit]
#.....
After=network.target
簡単に見ると、ネットワーク接続に依存するシステム上のすべてのotherサービスにこのディレクティブが含まれていることが確認できます。
また、systemdを使用するどのディストリビューションにも移植可能です。ユニットファイルはArch、Fedora、RHEL 7、Debianの将来のバージョンで同じになります...
startネットワーク接続のサービス(Archのスクリプトや独自のサービスなど)は、their ownユニットファイルでそのように指定する必要があります。
[Unit]
Wants=network.target
Before=network.target
この記事にポイントを追加したかったのです。現在(2015年夏)RHEL7/CentOS 7では、IPv6ネットワークが起動する前にnetwork-online.targetが誤って設定されているため、
Wants=network-online.target
After=network-online.target
また、IPv6アドレスに明示的にバインドするサービス定義では、IPv6が起動して実行される前に開始され、失敗する可能性があります。
[Unit]
After=systemd-networkd.service
私のために働く。