準備プロトコルの不一致
Wielandが示唆したようType
に、サービスの重要性は重要です。その設定は、systemdがサービスが話すことを期待する準備プロトコルを示します。simple
サービスはすぐに準備ができていると想定されます。forking
サービスは、その最初のプロセスが終了し、その後、子をフォークし、後に準備ができていると解釈されます。dbus
サービスは、サーバー、デスクトップバスに表示されたときに準備ができて取られます。などなど。
サービスが行うことと一致するようにサービスユニットで宣言された準備プロトコルを取得できない場合、問題が発生します。準備プロトコルの不一致により、サービスが正しく開始されないか、(より一般的に)systemdによって失敗と(誤って)診断されます。サービスがsystemdの開始に失敗したと見なされる場合、サービスの非アクティブな状態に適切に戻すために、(その観点から)障害の一部として実行されたままになっているサービスのすべての孤立した追加プロセスが強制的に強制終了されます状態。
あなたはまさにこれをやっています。
まず第一に、単純なもの:またはにsh -c
一致しません。 Type=simple
Type=forking
simple
プロトコル、初期処理をするものと解釈されることサービスプロセス。しかし実際には、sh -c
ラッパーは実際のサービスプログラムを子プロセスとして実行します。だから、MAINPID
うまくいかないとExecReload
スターターのため、作業を停止します。をType=simple
使用するsh -c 'exec …'
場合、最初に使用する か使用しないかのいずれかを行う必要がありますsh -c
。後者は、多くの場合、一部の人が考えるよりも正しいコースです。
sh -c
Type=forking
どちらとも一致しません。forking
サービスの準備プロトコルは非常に具体的です。最初のプロセスでは、子をフォークしてから終了する必要があります。systemdは、このプロトコルにタイムアウトを適用します。初期プロセスが割り当てられた時間内に分岐しない場合、準備ができていないことになります。割り当てられた時間内に初期プロセスが終了しない場合、それも失敗です。
ある不必要な恐怖 ossec-control
それは複雑なもの、つまりそのossec-control
スクリプトに私たちを連れて行きます。
それは判明、それはシステム5だとrc
スクリプトその4〜10のプロセスオフフォーク、あまりにも自分の順番フォークして終了でいる自分。ループ、競合状態、それらを回避するための任意のs、ハーフスタート状態でシステムを停止させる可能性のある障害モードを使用して、rc
サーバープロセスのセット全体を1つのスクリプトで管理しようとするSystem 5 スクリプトの1つです。 20年前にAIX System Resource Controllerやdaemontoolsのようなものを発明させた他のすべての恐怖。そして、letのは、特有の実装に、それはその場で書き換えたことをバイナリディレクトリに隠されたシェルスクリプトを忘れていないし、動詞を。for
sleep
enable
disable
だからあなた/bin/sh -c '/var/ossec/bin/ossec-control start'
が起こることはそれです:
- systemdは、サービスプロセスとなるものをフォークします。
- それがforkするシェル
ossec-control
です。
- その結果、4〜10人の孫が分岐します。
- 孫はすべて分岐し、順番に終了します。
- ひ孫はすべて分岐し、並行して終了します。
ossec-control
終了します。
- 最初のシェルが終了します。
- サービスプロセスであった偉大な-great-孫が、作業の試合のためにこのようもない
forking
にもsimple
即応プロトコル、systemdに全体が失敗したと、それがシャットダウンしてバックアップなどのサービスを検討します。
systemdでは、この恐怖は実際には必要ありません。どれでもない。
systemdテンプレートサービスユニット
代わりに、非常に単純なテンプレートユニットを記述します。
[単位]
Description = OSSEC HIDS%iサーバー
After = network.target
[サービス]
Type = simple
ExecStartPre = / usr / bin / env / var / ossec / bin /%p-%i -t
ExecStart = / usr / bin / env / var / ossec / bin /%p-%i -f
[インストール]
WantedBy = multi-user.target
これをとして保存します/etc/systemd/system/ossec@.service
。
さまざまな実際のサービスは、このテンプレートのインスタンス化であり、次の名前が付けられています。
ossec@dbd.service
ossec@agentlessd.service
ossec@csyslogd.service
ossec@execd.service
ossec@agentd.service
ossec@logcollector.service
ossec@syscheckd.service
ossec@maild.service
ossec@analysisd.service
ossec@remoted.service
ossec@monitord.service
その後、有効化および無効化機能はサービス管理システムから直接提供され(RedHatバグ752774が修正されています)、非表示のシェルスクリプトは不要です。
systemctl enable ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remoted ossec @ syscheckd ossec @ monitord
さらに、systemdは実際の各サービスについて直接知り、追跡することができます。でログをフィルタリングできますjournalctl -u
。個々のサービスがいつ失敗したかを知ることができます。どのサービスが有効化され実行されているかがわかっています。
ちなみに、他の多くの場合と同じようにType=simple
、-f
オプションもここにあります。実際、ごく少数のサービスがのdintによって準備ができていることを通知しexit
ますが、これらはこのようなケースでもありません。しかし、それがforking
タイプの意味です。メインでの野生のサービスは、それがデーモンがすべきことであるという誤った受信知恵の概念のために分岐して終了します。実際、そうではありません。それは1990年代以来ではありません。追いつく時です。
参考文献