初めてのsystemd
単位ファイルを書いています
Type
については、いくつかの選択肢があります。forking
, simple
, などです。このトピックに関する Redhat ドキュメンテーション (表 9.9) を読みましたが、いつどのオプションを使えばいいのかよくわかりません
Any guidelines?
31 leeyuiwah 2017-12-06
コマンドラインから手動でサービスを起動すると(nohup
prefixコマンドや&
サフィックスを使わずにバックグラウンドで実行する、言い換えれば.service
ファイルのExecStart=
行に置くようなコマンドを実行するだけ)、何が起こるのでしょうか?
a) サービスが起動して実行され続け、Control-Cを押すか他の方法でサービスを停止するまでプロンプトが戻らない場合: Type = simple
が正しい選択です
b) プロンプトが戻ってきても、サービスがバックグラウンドで実行され続けている場合 (すなわち、サービスが自分自身でデーモン化している場合)、 Type = forking
が正しい選択です
c) サービスがその仕事をして、何も実行したままにせずにプロンプトに戻る場合 (つまり、サービスがカーネルの設定を調整したり、他の何かにコマンドを送ったり、似たようなことをしたりするだけ)、Type = oneshot
が正しい選択かもしれません。この場合、サービスの ExecStart
は何かを「設定」するためのコマンドであり、ExecStop
はそれを「設定解除」するための対応するコマンドであるかもしれません。このタイプは通常 RemainAfterExit=true
の恩恵を受けるので、systemd はこのサービスの “状態” を、最近 “設定” されたか “設定解除” されたかに応じて追跡します
他のType
の値は特殊なケースです。例えば、サービスがD-Bus接続を利用している場合、Type = dbus
が最良の選択かもしれない。これは systemd
にその事実を認識させ、systemd はこのサービスが D-Bus 上に存在することで、このサービス (とそれに依存するもの) を追跡します
Type = notify
を使用するためには、環境変数$NOTIFY_SOCKET
で指定されたUnixソケットに接続し、必要に応じてそのソケットにメッセージを書き込むことで、プロセスの状態を報告できるようにしなければなりません。また、サービスファイルには、通知ソケットへのアクセスを許可するための NotifyAccess
オプションを適切に指定しなければなりません
これらのメッセージを送信するためにコマンドラインユーティリティ systemd-notify
と C ライブラリ関数 sd_notify(3)
がありますが、どちらも要件に合わない場合は、独自のメッセージ送信者を実装することができます。必要なメッセージは非常にシンプルで、シェル変数の代入のようなものです。例えば、サービスの起動が正常に完了し、受信したリクエストに対応する準備ができたことを通知するために、サービスはソケットに printf "READY=1\n"
の出力に相当する文字列を送信しなければなりません。認識されるメッセージの詳細については man 3 sd_notify
を参照してください
注意: 多くのUnixスタイルのシステムに移植できるように設計された多くのサービスアプリケーションは、デフォルトではb)のように振る舞うかもしれませんが、オプションを追加することで、a)のように動作するようにすることができます(通常、”don’t fork”、”keep running in foreground”、”don’t daemonize “などと記述されています)。その場合、オプションに他の副作用がない場合は、オプションを追加してa)型の動作を使うことがsystemd
では望ましいでしょう
61 telcoM 2017-12-06