リロード時にデーモンを強制終了して再起動するようにsystemdを設定するにはどうすればよいですか?


12

systemdを使用して制御したい旧式のデーモンがあります。構成ファイルが変更された場合は、強制終了して再起動する必要があります。つまり、設定ファイルを編集した後systemctl reload MYSERVICE、プロセスを終了して再起動する必要があります。

試行1:デフォルトを試します。これは、デーモンを開始する方法をsystemdに通知しますが、再ロードする方法は通知しません。

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

その結果、startそしてrestart仕事が、reloadこのエラーを与えます:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

試み2:プロセスを強制終了する方法を教えてください。これによりプロセスは強制終了されますが、systemdはプロセスを再起動しません。

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...に続く...

# systemctl daemon-reload
# systemctl reload MYSERVICE

...プロセスを強制終了しますが、自動的に再起動されません。

試行3:ExecReloadを使用してプロセスも再起動します。これはいくつかの理由で失敗します:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

...私が得るエラーメッセージ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

ReloadType = kill_and_restartか何かがあると思いますが、そのような運はありません。

リロード時にデーモンを強制終了して再起動するようにsystemdに指示する方法は?


これは本当にリロードにシューホーンする必要がありますか?デーモンを賢く動作させることはできませんか?
マイケルハンプトン

@MichaelHamptonに感謝しますが、これは私がプログラムを書き直すことができる状況ではありません。あなたの有益な提案に感謝します。そうは言っても、これは一般的なsystemdのユースケースであり、標準的な回答が多くの人に役立つ可能性があると確信しています。
TomOnTime 2016年

1
私は答えが誰かを助けるかもしれないと確信しているので、私は質問に賛成票を投じました。これが一般的なユースケースかどうかはわかりません。systemdを5年ほど使用していて、世界に公開されたその日からほとんど、この種のシナリオを試みる人について聞いたのを思い出すのはこれが初めてです。詳細が足りないので誤解している可能性があります。
マイケルハンプトン

回答:


16

答えは、「あなたはしません」です!しかし、良いニュースがあります。

systemdの哲学は、リロードはオプションであり、真のリロード機能がない場合は未定義のままにしておくことです。「真のリロード機能」は、サービスを強制終了して再起動しない、またはサービスにそのPIDを変更させないリロードとして定義します。言い換えると、systemdは、存在する機能を反映したいだけです。

代わりに、systemctl reload-or-restart存在する場合は再読み込みを行い、存在しない場合は再起動を行うようにしてください。

マニュアルページから...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

したがって、(1)ExecReloadを空白のままにし、(2)使用systemctl reload-or-restart MYSERVICEし、(3)すべて設定する必要があります。

ExecReloadを使用してサービスを強制終了して再起動する方法を定義しようとすると、新しいPIDが設定され、systemdが混乱します。


3

systemdの哲学はreloadオプションであり、systemdのユーザーは、すべてのサービスについて、を呼び出すreloadことによってそれを呼び出すか、偽装するかを知っている必要がありますrestart

したがって、あなたの質問に対する答えは、「それは機能しない、そして機能してはならない。これを次の上位層で解決してください。」です。

言い換えると、systemdは、基になるサービスが真のリロード機能をサポートしている場合にのみ「reload」を実装することを求めています...つまり、サービスを強制終了して再起動しない、またはサービスにPIDを変更させないリロード。言い換えると、systemdは、存在する機能を反映したいだけです。

あなたは自分自身に問いかけるかもしれません:しかしExecReload、サービスを強制終了して再起動できるようにすることで「偽の」リロードを実装できれば、もっと簡単ではないでしょうか?次にsystemctl reload FOO、すべてのサービスに使用でき、サポートしているサービスとサポートしていないサービスを覚えておく必要はありませんか?

はい、それは簡単ですが、それはsystemdの方法ではありません。Systemdは、呼び出し元reloadがサービスに存在するかどうかを認識できるようにしたいと考えています。Systemdは、存在する機能への共通のインターフェースになりたいと考えています。ギャップを埋める責任はありません。

たとえば、puppetは、systemd駆動型サービスにはプロセスがないためreloadデフォルトでプロセスを強制終了して再起動すると想定しています。Service []タイプがリロードの存在を指定する方法を追加し、通知でそれを使用する必要がある場合、どのサービスがネイティブリロードを持っているか、持っていないかを知る必要があります。シェフと他のすべてのシステムも同じことを学ぶ必要があります。なぜならsystemdはその層でそれを解決したいと考えているからです。(MiniRant:プロセスを開始するために、systemdはすべてを認識し、すべてをマウントし、すべての名前空間をカスタマイズするi-do-everything-at-my-layerシステムであるように思われます。したがって、なぜそれができないのかはわかりません。この哲学をリロードに拡張します。たぶん、作者の1人がここに呼びかけることができます。)


1
がありsystemctl reload-or-restart、サポートしている場合はサービスをリロードし、サポートしていない場合は再起動します。Puppetがこの仮定を行う理由はわかりません。
マイケル・ハンプトン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.