Access from '3.145.2.6'
You are in US.
It is 19:00 JST now.
名前
systemd.service-サービスユニット構成
概要
service.service
説明
名前が .service
で終わるユニット構成ファイルは systemd によって制御・監視されるプロセスに関する情報をエンコードする。
このマニュアルページには、このユニットタイプに固有の構成オプションが列記される。
すべてのユニット構成ファイルに共通するオプションについては systemd.unit(5) を参照。
一般的な構成要素は、一般に [Unit]
と [Install]
セクションで構成される。
サービス固有の構成オプションは [Service]
セクションで構成される。
追加のオプションは、コマンドが実行される実行環境を定義する systemd.exec(5) と、サービスのプロセスの終了方法を定義する systemd.kill(5)、サービスのプロセスのリソース制御設定を構成する systemd.resource-control(5) に列記されている。
サービスが特定の名前で要求されたがユニット構成ファイルが見つからない場合、 systemd は同じ名前( .service
拡張子が削除された)の SysV init スクリプトを探し、そのスクリプトからサービスユニットを動的に作成する。
これは SysV との互換性のために役立ちる。
この互換性は非常に包括的だが 100% ではない。
非互換性の詳細については SysV との非互換性を参照。
サービステンプレート
systemd サービスは service@argument.service
構文を介して単一の引数を取ることが可能。
このようなサービスは instantiated
サービス(インスタンス化されたサービス)と呼ばれ、引数パラメーターなしのユニット定義は template
と呼ばれる。
たとえば dhcpcd@.service
サービステンプレートは、ネットワークインターフェイスをパラメーターとして使用して、インスタンス化されたサービスを形成する。
サービスファイル内では、このパラメーターまたは instance name
に %
指定子を使用してアクセスできる。
詳細については systemd.unit(5) を参照。
自動依存関係
暗黙的な依存関係
次の依存関係が暗黙的に追加される。
Type=dbus
が設定されたサービスはdbus.socket
上のタイプRequired=
とAfter=
の依存関係を自動的に取得する。- ソケットでアクティブ化されるサービスは、自動的に
After=
依存関係を介して.socket
ユニットをアクティブ化した後に自動的に実行される。サービスはまた、自動的にWants=
とAfter=
の依存関係を介して、Sockets= に列記されているすべての.socket
ユニットを呼び出する。
systemd.exec(5) と systemd.resource-control(5) に記載されているように、実行・リソース制御パラメーターの結果として、暗黙的な依存関係が追加される場合がありる。
デフォルトの依存関係
DefaultDependencies=no
が設定されていない限り、次の依存関係が追加される。
-
サービスユニットには
sysinit.target
に対するタイプRequired=
とAfter=
の依存関係、basic.target
に対するタイプAfter=
の依存関係、shutdown.target
に対するタイプConflicts=
とBefore=
の依存関係がありる。これにより、通常のサービスユニットが基本的なシステム初期化を取り込み、システムのシャットダウン前に完全に終了する。このオプションを無効にできるのは、早期ブートまたはシステムシャットダウンの遅延に関連するサービスのみ。 -
インスタンス化されたサービスユニット(つまり、名前に
@
が付いたサービスユニット)は、デフォルトで、特定のテンプレートのすべてのインスタンスを含む、テンプレートユニットにちなんで名付けられたテンプレートごとのスライスユニット(systemd.slice(5) を参照)に割り当てられる。
このスライスは通常、シャットダウン時にすべてのテンプレートインスタンスとともに停止する。
それが望ましくない場合は、テンプレートユニットでDefaultDependencies=no
を設定し、DefaultDependencies=no
も設定する独自のテンプレート単位のスライスユニットファイルを定義するか、テンプレートユニットでSlice=system.slice
(または別の適切なスライス)を設定する。詳細は systemd.resource-control(5) を参照。
オプション
サービスファイルには [Service]
セクションを含める必要がありる。
このセクションには、サービスとサービスが監視するプロセスに関する情報が含まれている。
このセクションで使用できるいくつかのオプションは、他のユニットタイプと共有される。
これらのオプションは systemd.exec(5), systemd.kill(5), systemd.resource-control(5) に記載されている。
サービスユニットの [Service]
セクションに固有のオプションは次のとおり。
Type=
このサービスユニットのプロセス起動タイプを設定する。
-
simple( ExecStart= が指定されていて Type= も BusName= も指定されていない場合のデフォルト)
サービスマネージャーは、メインサービスプロセスがフォークされた直後にユニットが開始されたと見なす。
ExecStart= で構成されたプロセスがサービスのメインプロセスであることが期待される。
このモードでは、メインサービスプロセスを作成した直後、サービスのバイナリを実行する前にサービスマネージャーが後続ユニットの開始にすぐに進むため、サービスマネージャーが即時開始する。
プロセスがシステム上の他のプロセスに機能を提供する場合は、サービスを開始する前にその通信チャネルをインストールする必要がある。(例:ソケットのアクティブ化を介して systemd によって設定されたソケット)
これは、サービスのバイナリを正常に呼び出すことができない場合でも(たとえば、選択したUser=
が存在しないか、サービスバイナリが見つからない場合)、 simple サービスのsystemctl start
コマンドラインが成功を報告することを意味する。 -
exec
exec タイプは simple に似ている。
しかしサービスマネージャはメインサービスバイナリが実行された直後にユニットが開始されたと見なす。
サービスマネージャはメインサービスバイナリが実行されるまで後続ユニットの開始を遅らせる。
(または言い換えれば、simple
はfork()
が戻った直後にさらにジョブを続行するが、exec
はサービスプロセスのfork()
とexecve()
の両方が成功するまで続行しません。
これは exec サービスのsystemctl start
コマンドを意味することに注意。
サービスのバイナリを正常に呼び出すことができない場合(たとえば選択したUser=
が存在しないか、サービスのバイナリが見つからない場合)は、失敗を報告する。 -
forking
ExecStart= で構成されたプロセスは、起動処理の一部としてfork()
を呼び出すことが期待される。
親プロセスは起動が完了し、すべての通信チャネルがセットアップされたときに終了することが期待されている。
子プロセスはメインサービスプロセスとして引き続き実行され、サービスマネージャーは親プロセスが終了したときにユニットが開始されたと見なす。
これは、伝統的な UNIX サービスの動作である。
この設定を使用する場合は systemd がサービスのメインプロセスを確実に識別できるように PIDFile= オプションも併用することをお勧めする。
systemd は親プロセスが終了するとすぐに後続ユニットの開始に進む。 -
oneshot
oneshot の動作は simple に似ている。
ただしサービスマネージャーはメインプロセスの終了後にユニットが開始されたと見なし、メインプロセスの終了後に後続ユニットを開始する。
RemainAfterExit= はこのタイプのサービスに特に役立つ。
Type= も ExecStart= も指定されていない場合、Type=oneshot
がデフォルトとして暗黙的に設定される。 -
dbus
dbus の動作は simple に似ている。
ただし BusName= で設定されているように、サービスが D-Bus 上のバス名を取得することが期待されている。
systemd は D-Bus バス名が取得された後、後続ユニットの開始に進む。
このオプションが設定されたサービスユニットは暗黙的にdbus.socket
ユニットへの依存関係を取得する。
BusName= が指定されている場合は dbus がデフォルトのタイプとなる。 -
notify
notify の動作は exec に似ている。
ただしサービスの起動が完了すると、サービスは sd_notify(3) または同等の呼び出しを介して通知メッセージを送信することが期待される。
systemd は、この通知メッセージが送信された後に後続ユニットの開始に進みる。
このオプションを使用する場合は NotifyAccess= を設定して systemd が提供する通知ソケットへのアクセスを開く必要がある。
NotifyAccess= がないか、またはnone
に設定されている場合は強制的にmain
に設定される。
現在Type=notify
はPrivateNetwork=yes
と組み合わせて使用すると機能しません。 -
idle
idle の動作は simple に非常に似ている。
ただしサービスプログラムの実際の実行は、すべてのアクティブなジョブがディスパッチされるまで遅延される。
これはシェルサービスの出力とコンソールのステータス出力のインターリーブを回避するために使用できる。
このタイプはコンソール出力を改善する場合のみ役立ち、一般的なユニット実行ツールとしては役に立たないことに注意。
このサービスタイプの効果は 5 秒間タイムアウトの影響を受け、その後サービスプログラムが呼び出される。
Type=simple
は、最も単純で最速のオプションであるため、可能な場合はいつでも実行時間の長いサービスに使用することをお勧めする。
ただし、このサービスタイプはサービスの起動失敗を伝播せず、サービスの初期化の完了に対する他のユニットの順序付けを許可しません。
IPC チャネルはサービスそのものによってのみ確立される。
(たとえば、クライアントが何らかの形式の IPC を介してサービスに接続する必要がある場合に役立つ)
ソケットまたはバスのアクティブ化などを介して事前にチャネルを確立するとは対照的に、多くの場合充分ではない可能性がある。
その場合、 notify または dbus(後者は、サービスが D-Bus インターフェースを提供する場合のみ)を使用することをお勧めする。これによりサービスプログラムコードは、サービスが正常に起動したと見なすタイミングと後続ユニットを続行するタイミングを正確にスケジュールできる。
notify サービスタイプは sd_notify()
または同等の API が適切なタイミングでサービスによって呼び出される必要があるため、サービスコードベースで明示的なサポートが必要。
サポートされていない場合は代わりに forking を使用: forking は伝統的な UNIX サービス起動プロトコルをサポートする。
最後に exec はサービスバイナリが呼び出されることを確認するのに充分であり、サービスバイナリ自体が初期化をまったく実行しない、あるいはほとんど実行しない場合(初期化が失敗する可能性が低い場合)のオプションになる場合がありる。
simple 以外のタイプを使用すると、サービスマネージャがサービスの初期化を完了するのを待つ必要があるため、ブートプロセスが遅延する可能性があることに注意。
したがって simple 以外のタイプを不用意に使用しないことをお勧めする。
(また、長時間実行されるサービスに idle または oneshot を使用することは一般に推奨されないことにも注意)
RemainAfterExit=
すべてのプロセスが終了した場合でも、サービスをアクティブと見なすかどうかを指定するブール値を取る。
デフォルトは no
。
GuessMainPID=
確実に決定できない場合に systemd がサービスのメイン PID を推測するかどうかを指定するブール値を取る。Type=forking
が設定されていて PIDFile= が設定されていない場合を除き、このオプションは無視される。
他のタイプの場合、または明示的に構成された PIDFile の場合、メイン PID は常にわかっているためである。
デーモンが複数のプロセスで構成されている場合、推測アルゴリズムが誤った結論をもたらす可能性がある。
メイン PID を特定できない場合、サービスの起動失敗の検出と自動再起動は正常に機能しません。
デフォルトは yes
。
PIDFile=
サービスの PID ファイルを参照するパスを取得する。Type=fork
に設定されているサービスでは、このオプションの使用をお勧めする。
指定されたパスは通常 /run/
配下のファイルを指す。
相対パスが指定されている場合は暗黙的に /run/
がパスの前に付けられる。
サービスマネージャーはサービスの起動後、 PIDFile に指定したファイルからサービスのメインプロセスの PID を読み取る。
サービスマネージャーはここで構成されたファイルに書き込みませんが、サービスがまだ存在する場合は、シャットダウン後にファイルを削除する。
PID ファイルは特権ユーザーが所有する必要はありませんが、非特権ユーザーが所有している場合、追加の安全制限が適用される。
ファイルは(直接的・間接的に)別のユーザーが所有するファイルへのシンボリックリンクではない場合がありる。
PID ファイルは、サービスに属しているプロセスを参照する必要がありる。
BusName=
このサービスに到達できる D-Bus バス名を取得する。
このオプションは Type=dbus
に設定されているサービスでは必須。
ExecStart=
サービスの開始時に実行される引数付きのコマンドを指定する。
値は、以下で説明する規則に従ってコマンド行に分割される(以下の コマンド行 のセクションを参照)。
Type=oneshot
でない限り、正確に 1 つのコマンドを指定する必要がありる。Type=oneshot
を使用する場合は 0 個以上のコマンドを指定できる。
コマンドは、同じディレクティブで複数のコマンド行を指定できる。
または、このディレクティブを複数回指定して、同じ効果を得ることができる。
空文字列がこのオプションに割り当てられている場合、開始するコマンドのリストはリセットされる。
このオプションを空文字列以前に割り当てても効果はありません。
ExecStart= が指定されていない場合、サービスには RemainAfterExit=yes
と少なくとも 1 つの ExecStop= 行が設定されている必要がありる。
( ExecStart= と ExecStop= の両方がないサービスは無効)
指定された各コマンドの最初の引数は、実行可能ファイルへの絶対パスか、スラッシュを含まない単純なファイル名でなければなりません。
ファイル名の前にはオプションでいくつかの特殊文字を付けることができる。
表1. 特別な実行可能接頭辞
接頭辞 | 効果 |
---|---|
@ |
実行可能パスの先頭に @ を付けると 2 番目に指定されたトークンが argv[0] として(実際のファイル名ではなく)実行されたプロセスに渡され、 2 番目のトークン以降に指定された引数が続く。 |
- |
実行可能パスの先頭に - が付いている場合、通常は失敗と見なされるコマンドの終了コード(つまり、ゼロ以外の終了ステータスまたはシグナルによる異常終了)が記録されるが、それ以上の影響はなく、成功と同等と見なされる。 |
+ |
実行可能パスの先頭に + が付いている場合、プロセスは完全な権限で実行される。このモードでは User= , Group= , CapabilityBoundingSet= またはファイルシステムのネームスペースオプション( PrivateDevices= , PrivateTmp= など)で構成された特権制限は、呼び出されたコマンド行に適用されません。(ただし他の ExecStart= , ExecStop= 等のコマンド行には影響する) |
! |
上記の + 文字と同様に、昇格された特権でコマンド行を呼び出すことができる。ただし + とは異なり、 ! 文字は User= , Group= , SupplementaryGroups= の効果のみを変更する。つまりユーザーとグループの資格情報に影響を与えるスタンザのみ。この設定は DynamicUser= と組み合わせることができる。この場合、コマンドが呼び出される前にユーザー / グループのペアが動的に割り当てられるが、資格情報の変更は実行されたプロセス自体に委ねらる。 |
!! |
この接頭辞は ! によく似ているが、アンビエント処理機能のサポートが欠如しているシステム、つまり AmbientCapabilities= のサポートがないシステムにのみ影響する。アンビエント機能をサポートしていないシステムとの互換性を維持しながら、可能な限り最小限の特権でプロセスを実行するためにアンビエント機能を利用するユニットファイルに使用することを目的としている。 !! が許可されないように構成されている場合でも、生成されたプロセスが資格情報と機能を破棄できるようにするために、 SystemCallFilter= と CapabilityBoundingSet= スタンザが暗黙的に変更される。さらにこの接頭辞が使用されているがアンビエント機能のサポートがないシステムが検出された場合、 AmbientCapabilities= はスキップされ、適用されません。アンビエント機能をサポートするシステムでは !! の効果は無い為、冗長な記述となる。 |
@
, -
と +
/ !
/ !!
のいずれかを併用でき、任意の順序で指定できる。
ただし +
, !
, !!
の使用はいずれか一度のみ。
これらの接頭辞は他のコマンド行の設定( ExecStartPre= , ExecStartPost= , ExecReload= , ExecStop= , ExecStopPost= )でもサポートされていることに注意。
複数のコマンドが指定されている場合、コマンドは、ユニットファイルに出現する順序で順次呼び出される。
コマンドの 1 つが失敗した(そして -
が前に付いていない)場合、他の行は実行されず、ユニットは失敗したと見なされる。
Type=forking
が設定されていない限り、このコマンド行から開始されたプロセスはデーモンのメインプロセスと見なされる。
ExecStartPre=, ExecStartPost=
ExecStart= のコマンドの前または後に実行される追加のコマンドを指定する。
構文は ExecStart= の場合と同じだが、複数のコマンド行が許可され、コマンドが順番に連続して実行される点が異なる。
これらのコマンドのいずれかが失敗した(そして -
が前に付いていない)場合、失敗後のコマンド行は実行されず、ユニットは失敗したと見なされる。
ExecStart= コマンドは -
接頭辞が付いていないすべての ExecStartPre= コマンドが正常に終了した後にのみ実行される。
ExecStartPost= コマンドは ExecStart= で指定されたコマンドが正常に呼び出された後にのみ実行される。
これは Type= によって決定される。
例:
Type=simple
またはType=idle
でプロセスが開始され、最後の ExecStart= の処理がType=oneshot
で正常に終了した場合- 初期化処理が
Type=forking
で正常に終了した場合 READY=1
がType=notify
で送信された場合- BusName= が
Type=dbus
で使用された場合
ExecStartPre= は長時間実行プロセスを開始するために使用できない場合があることに注意する。
ExecStartPre= を介して呼び出されたプロセスによって分岐されたすべてのプロセスは、次のサービスプロセスが実行される前に強制終了される。
ExecStartPre= , ExecStart= または ExecStartPost= で指定されたコマンドのいずれかが失敗する(そして -
が前に付いていない)か、サービスが完全に起動する前にタイムアウトになる場合、 ExecStopPost= で指定されたコマンドの実行が続行されることに注意する。
ExecStop= のコマンドはスキップされる。
ExecReload=
サービスで構成の再読み込みをトリガーするために実行するコマンドを指定する。
引数は上記の ExecStart= で説明したのと同じスキームに従って、複数のコマンド行を取りる。
この設定の使用はオプション。
ExecStart= と同じスキームに従って、指定子と環境変数の置換がサポートされている
追加の特別な環境変数が 1 つ設定される。
既知の場合 $MAINPID
がデーモンのメインプロセスに設定される。
次のようなコマンド行に使用できる。
/bin/kill -HUP $MAINPID
ただし、これは非同期操作であり、複数のサービスのリロードを相互に順序付けるのに適していないため、上記の例のようにシグナルを送信してデーモンをリロードすることは通常、適切な選択ではありません。
ExecReload= でデーモンの構成リロードをトリガーするだけではなく、デーモンが完了するのを同期的に待機するコマンドを設定することを強くお勧めする。
ExecStop=
ExecStart= で開始されたサービスを停止するために実行するコマンドを指定する。
引数は上記の ExecStart= で説明したのと同じスキームに従って、複数のコマンド行を取りる。
この設定の使用はオプション。
このオプションで構成されたコマンドが実行された後はサービスが停止し、残っているすべてのプロセスは KillMode=
の設定に従って終了する(systemd.kill(5) を参照)。
このオプションが指定されていない場合、サービスの停止が要求されたときに KillSignal=
で指定されたシグナルを送信することによってプロセスが終了する。$MAINPID
を含む指定子と環境変数の置換がサポートされている。
サービスに終了を要求するだけ(たとえば、何らかの形式の終了信号をキューに入れて)では不充分であり、サービスが終了するまで待機しないことに注意。
サービスの残りのプロセスは、コマンドが終了した直後に上記のように KillMode=
と KillSignal=
に従って強制終了されるため、正常に停止しない場合がありる。
したがって指定されたコマンドは非同期操作ではなく同期操作である必要がありる。
ExecStop= で指定されたコマンドは、サービスが最初に正常に開始されたときにのみ実行されることに注意。
サービスがまったく開始されなかった場合、または起動が失敗した場合、
たとえば ExecStart= , ExecStartPre= または ExecStartPost= で指定されたコマンドのいずれかが失敗した場合(そして先頭に -
が付いていなかった場合)
またはタイムアウトした場合は呼び出されません。
サービスが正しく起動できず、サービスが再度シャットダウンされた場合は、 ExecStopPost= を使用してコマンドを呼び出する。
またサービスの再起動要求は、停止操作とそれに続く開始操作として実装されることに注意。
つまりサービスの再起動操作中に ExecStop= と ExecStopPost= が実行される。
クリーン終了を要求するサービスと通信するコマンドには、この設定を使用することをお勧めする。
このオプションで指定されたコマンドが実行されるとき、サービスはまだ完全に稼働しており、すべてのコマンドに正しく反応できるように想定する必要がありる。
事後のクリーンアップ手順では、代わりに ExecStopPost= を使用する。
ExecStopPost=
サービスの停止後に実行される追加のコマンドを指定する。
これには ExecStop= で構成されたコマンドが使用された場合、サービスに ExecStop= が定義されていない場合、またはサービスが予期せず終了した場合が含まれる。
引数は ExecStart= で説明したのと同じスキームに従って複数のコマンド行を取る。
これらの設定の使用はオプション。
指定子と環境変数の置換をサポート。
ExecStop= とは異なり、この設定で指定されたコマンドはサービスが正常に起動できず、再びシャットダウンされたときに呼び出される。
サービスの正常な起動に失敗した場合でも実行されるクリーンアップ操作には、この設定を使用することをお勧めする。
この設定で構成されたコマンドはサービスが途中で起動に失敗し、不完全に初期化されたデータが残った場合でも動作できる必要がある。
サービスのプロセスは、この設定で指定されたコマンドが実行されたときにすでに終了しているため、それらとの通信を試みるべきではありません。
この設定で構成されたすべてのコマンドは $SERVICE_RESULT
, $EXIT_CODE
, $EXIT_STATUS
環境変数で設定されたメインプロセスの終了コードとステータスだけでなく、サービスの結果コードで呼び出されることに注意する。
詳細については systemd.exec(5) を参照。
RestartSec=
Restart= で設定されているサービスの再起動を実行する前にスリープする時間を設定する。
秒単位の単位のない値、または 5min 20s
などのタイムスパン値を取る。
デフォルトは 100ms
。
TimeoutStartSec=
起動を待つ時間を設定する。
デーモンサービスが構成された時間内に起動完了を通知しない場合、サービスは失敗したと見なされ、再びシャットダウンされる。
秒単位の単位のない値、または 5min 20s
などのタイムスパン値を取る。infinity
を渡すとタイムアウトロジックを無効にする。Type=oneshot
が使用される場合を除いて、デフォルトはマネージャー構成ファイルの DefaultTimeoutStartSec=
。
この場合、タイムアウトはデフォルトで無効になっている(systemd-system.conf(5) を参照)。
Type=notify
のサービスが EXTEND_TIMEOUT_USEC=...
を送信すると、これにより開始時間が TimeoutStartSec= を超えて延長される場合がある。
このメッセージの最初の受信は TimeoutStartSec= を超える前に発生する必要がある。
開始時間が TimeoutStartSec= を超えた後、サービスの起動状態が READY=1
で終了するまで EXTEND_TIMEOUT_USEC=...
を繰り返し、サービスマネージャーがサービスの開始を継続できるようにする。
(sd_notify(3) を参照)
TimeoutStopSec=
このオプションには 2 つの目的がある。
最初に、各 ExecStop= コマンドを待機する時間を構成する。
それらのいずれかがタイムアウトした場合、後続の ExecStop= コマンドはスキップされ、サービスは SIGTERM
によって終了される。
ExecStop= コマンドが指定されていない場合、サービスはすぐに SIGTERM
を取得する。
次に、サービス自体が停止するまで待機する時間を構成する。
指定した時間内に終了しない場合は SIGKILL
によって強制終了される(systemd.kill(5) の KillMode=
を参照)。
秒単位の単位のない値、または 5min 20s
などのタイムスパン値を取りる。infinity
を渡すとタイムアウトロジックを無効にする。
デフォルトは、マネージャー構成ファイルの DefaultTimeoutStopSec=
である(systemd-system.conf(5) を参照)。
Type=notify
のサービスが EXTEND_TIMEOUT_USEC=...
を送信すると、停止時間が TimeoutStopSec= を超えて延長される可能性がある。
このメッセージの最初の受信は TimeoutStopSec= を超える前に行われる必要があり、停止時間が TimeoutStopSec= を超えた後、 EXTEND_TIMEOUT_USEC=...
を繰り返して、サービスが停止することを許可する。
(sd_notify(3)を参照)
TimeoutSec=
TimeoutStartSec= と TimeoutStopSec= の両方を指定された値に設定するための省略形。
RuntimeMaxSec=
サービスを実行する最大時間を構成する。
これが使用され、サービスが指定された時間より長くアクティブであった場合、サービスは終了し、障害状態になる。
この設定は、アクティベーションが完了した直後に終了するため Type=oneshot
サービスには影響しません。infinity
(デフォルト)を渡すと実行時の制限を構成しません。
Type=notify
のサービスが EXTEND_TIMEOUT_USEC=...
を送信すると、実行時間が RuntimeMaxSec= を超えて延長される可能性がある。
このメッセージの最初の受信は RuntimeMaxSec= を超える前に発生する必要があり、実行時間が RuntimeMaxSec= を超えて延長されると、サービスマネージャーはサービスの実行を許可する。
サービスがインターバル中に “EXTEND_TIMEOUT_USEC = …”を繰り返す場合、 STOPPING=1
(または termination)によってサービスのシャットダウンが達成されるまで指定される。
(sd_notify(3)を参照)
WatchdogSec=
サービスのウォッチドッグタイムアウトを設定する。
ウォッチドッグは起動が完了するとアクティブになる。
サービスは WATCHDOG=1
を使用して定期的に sd_notify(3) を呼び出す必要がある(つまり keep-alive ping
)。
そのような 2 つの呼び出しの間の時間が構成された時間よりも長い場合、サービスは障害状態になり SIGABRT
(または WatchdogSignal=
で指定されたシグナル)で終了する。
Restart= を on-failure
, on-watchdog
, on-abnormal
または always
に設定すると、サービスは自動的に再起動される。
ここで設定された時間は WATCHDOG_USEC=環境変数
で実行されたサービスプロセスに渡される。
これにより、サービスでウォッチドッグサポートが有効になっている場合、デーモンは keep-alive ping
ロジックを自動的に有効にすることができる。
このオプションを使用する場合は NotifyAccess= を設定して、 systemd が提供する通知ソケットへのアクセスを開く必要がありる。
NotifyAccess= が設定されていない場合、暗黙的に main に設定される。
デフォルトは 0 でこの機能は無効。
サービスは、サービスマネージャーがウォッチドッグキープアライブ通知を予期しているかどうかを確認できる。
詳細については sd_watchdog_enabled(3) を参照。
sd_event_set_watchdog(3) を使用して、自動ウォッチドッグ通知サポートを有効にすることができる。
Restart=
サービスプロセスが終了するか、強制終了されるか、タイムアウトに達したときにサービスを再起動するかどうかを構成する。
サービスプロセスはメインサービスプロセスである場合があるが、 ExecStartPre= , ExecStartPost= , ExecStop= , ExecStopPost= または ExecReload= で指定されたプロセスの 1 つである場合もある。
プロセスの停止が systemd 操作(サービスの停止または再起動など)の結果である場合、サービスは再起動されません。
タイムアウトには、ウォッチドッグ keep-alive ping
期限の欠落、サービスの開始、再読み込み、停止操作のタイムアウトが含まれる。
以下のいずれかを取る。
-
no(デフォルト)
サービスは再起動されません。 -
on-success
サービスプロセスが正常に終了した場合にのみ再起動される。
このコンテキストでは、正常終了は以下が該当する。- 0 の終了コード
- シグナル
SIGHUP
,SIGINT
,SIGTERM
またはSIGPIPE
のいずれか - SuccessExitStatus= で指定された終了ステータスとシグナル
-
on-failure
プロセスが 0 以外の終了コードで終了し、シグナル(コアダンプを含むが、前述の 4 つのシグナルを除く)によって操作が終了したとき(例えば reload)、タイムアウトして構成されたウォッチドッグタイムアウトがトリガーされたときにサービスが再起動される。 -
on-abnormal
プロセスがシグナル(上記の 4 つのシグナルを除くコアダンプを含む)によって終了したとき、操作がタイムアウトしたとき、またはウォッチドッグタイムアウトがトリガーされたときに、サービスが再起動される。 -
on-watchdog
サービスのウォッチドッグタイムアウトが期限切れになった(シグナルによって異常終了したか、タイムアウトに達した)場合にのみ、サービスが再起動される。 -
on-abort
キャッチされていないシグナルがクリーン終了ステータスとして指定されていないためにサービスプロセスが終了した場合にのみ、サービスが再起動される。 -
always
正常に終了したかどうかに関係なく、サービスは再起動される。
表2. 終了の原因と、それらに対する Restart=
設定の影響
Restart 設定 / 終了の原因 | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog |
---|---|---|---|---|---|---|---|
Clean exit code or signal | X | X | |||||
Unclean exit code | X | X | |||||
Unclean signal | X | X | X | X | |||
Timeout | X | X | X | ||||
Watchdog | X | X | X | X |
上記の設定の例外として、 RestartPreventExitStatus= で終了コードまたはシグナルが指定されている場合、または systemctl stop
または同等の操作でサービスが停止している場合、サービスは再起動されません。
また RestartForceExitStatus= で終了コードまたはシグナルが指定されている場合、サービスは常に再起動される。
サービスの再起動は StartLimitIntervalSec=
と StartLimitBurst=
で構成されたユニット開始レート制限の影響を受けることに注意。
詳細については systemd.unit(5) を参照。
再起動されたサービスは、開始制限に達した後でのみ障害状態になる。
エラーからの自動回復を試みて信頼性を向上させるために、これを on-failure
に設定することは、長時間実行サービスにおいて推奨される選択。
独自の選択で終了できる(そしてすぐに再起動しないようにする)サービスの場合は on-abnormal
を代用することができる。
SuccessExitStatus=
メインサービスプロセスから返されたときに、正常終了コード 0 とシグナル SIGHUP
, SIGINT
, SIGTERM
, SIGPIPE
に加えて、正常終了と見なされる終了ステータス定義のリストを取得する。
終了ステータス定義はスペースで区切られた数値の終了コード、または終了シグナル名のいずれか。
SuccessExitStatus = 1 2 8 SIGKILL
この例では終了コード 1, 2, 8 と終了シグナル SIGKILL
がクリーンサービス終了と見なされるようにする。
このオプションは複数回表示される場合がある。
その場合、正常終了ステータスのリストがマージされる。
空の文字列がこのオプションに割り当てられている場合、リストはリセットされ、空文字列以前のすべての割り当ては無効になる。
RestartPreventExitStatus=
メインサービスプロセスから返されたときに Restart= で構成された再起動設定に関係なく、サービスの自動再起動を防止する終了ステータス定義のリストを取得する。
終了ステータスの定義は数値の終了コード、または終了シグナル名のいずれかであり、スペースで区切られる。
デフォルトでは空のリストになっているため、構成された再始動ロジックから終了ステータスは除外されません。
RestartPreventExitStatus = 1 6 SIGABRT
この例では終了コード 1 と 6 そして終了シグナル SIGABRT
によってサービスが自動的に再起動されないようにする。
このオプションは複数回表示される場合がある。
その場合、再起動防止ステータスのリストがマージされる。
空の文字列がこのオプションに割り当てられている場合、リストはリセットされ、空文字列以前のすべての割り当ては無効になる。
RestartForceExitStatus=
メインサービスプロセスから返されたときに Restart= で構成された再起動設定に関係なく、サービスの自動再起動を強制する終了ステータス定義のリストを取得する。
引数の形式は RestartPreventExitStatus= に似ている。
RootDirectoryStartOnly=
ブール引数を取る。true
の場合 RootDirectory=option
(詳細については systemd.exec(5) を参照)で構成されたルートディレクトリは、 ExecStart= で開始されたプロセスにのみ適用され、他の ExecStartPre= , ExecStartPost= , ExecReload= , ExecStop= , ExecStopPost= のコマンドには適用されません。false
の場合、設定はすべての構成済みコマンドに同じ方法で適用される。
デフォルトは false
。
NonBlocking=
ソケットベースのアクティブ化を介して渡されるすべてのファイル記述子に O_NONBLOCK フラグを設定する。
true の場合、ファイル記述子ストレージロジック(詳細については FileDescriptorStoreMax= を参照)を介して渡されたものを除くすべてのファイル記述子 >= 3(つまり stdin
, stdout
, stderr
を除く)は、 O_NONBLOCK フラグが設定されているため、非ブロックモードである。
このオプションは systemd.socket(5) で説明されているように、ソケットユニットと組み合わせた場合にのみ役立ち、以前にファイル記述子ストアなどに保存されたファイル記述子には影響しません。
デフォルトは false 。
NotifyAccess=
sd_notify(3) 呼び出しでアクセスできるように、サービスステータス通知ソケットへのアクセスを制御する。
以下のいずれかを取る。
-
none(デフォルト)
サービスプロセスからのデーモンステータスの更新は受け入れられず、すべてのステータス更新メッセージは無視される。 -
main
サービスのメインプロセスから送信されたサービスの更新のみが受け入れられる。 -
exec
Exec*=commands
の 1 つから発生したメインプロセスまたは制御プロセスのいずれかから送信されたサービス更新のみが受け入れられる。 -
all
サービスのコントロールグループのすべてのメンバーからのすべてのサービスの更新が受け入れられる。
このオプションは Type=notify
または WatchdogSec= を使用する場合に通知ソケットへのアクセスを開くように設定する必要がある(上記を参照)。
これらのオプションが使用されているが NotifyAccess= が構成されていない場合、暗黙的に main に設定される。
sd_notify() 通知は PID 1 がメッセージを処理する時点で送信プロセスがまだ存在する場合、または送信プロセスがサービスマネージャーによって明示的にランタイム追跡されている場合にのみ、ユニットに正しく関連付けられることに注意。
後者は、サービスマネージャーが最初にプロセスを分岐した場合、つまり main または exec に一致するすべてのプロセスの場合となる。
逆に、ユニットの補助プロセスが sd_notify() メッセージを送信してすぐに終了する場合、 NotifyAccess=all
が設定されていてもサービスマネージャーはメッセージをユニットに適切に関連付けることができないため、メッセージを無視する。
Sockets=
サービス開始時にソケットファイル記述子を継承するソケットユニットの名前を指定する。
通常、この設定を使用する必要はありません。
ユニットがサービスと同じ名前を共有しているすべてのソケットファイル記述子(異なるユニット名の拡張子が適用される)は、生成されたプロセスに渡される。
同じソケットファイル記述子が複数のプロセスに同時に渡される場合があることに注意。
また着信ソケットトラフィックでは、最終的にソケットファイル記述子を継承するように構成されているサービスとは異なるサービスがアクティブになる場合があることにも注意。
言い換えると .socket
ユニットの Service=
設定は、それが参照する .service
の Sockets= 設定の逆と一致する必要はありません。
このオプションは複数回表示される場合がある。
その場合、ソケットユニットのリストがマージされる。
空の文字列がこのオプションに割り当てられている場合、ソケットのリストはリセットされ、空文字列以前に指定された設定は効果がありません。
FileDescriptorStoreMax=
sd_pid_notify_with_fds(3) の FDSTORE=1
メッセージを使用して、サービスのサービスマネージャーに保存できるファイル記述子の数を構成する。
これは、明示的な要求またはクラッシュ後に状態を失うことなく再起動できるサービスを実装するのに役立つ。
再起動中に閉じてはならない開放中のソケットやその他のファイル記述子は、この方法で保存できまる。
アプリケーションの状態は /run
内のファイルにシリアル化することも、 memfd_create(2) メモリファイル記述子に保存することもできる。
デフォルトは 0 。
つまりサービス記述子にファイル記述子を保存することはできない。
特定のサービスからサービスマネージャに渡されたすべてのファイル記述子は、次回のサービス再起動時にサービスのメインプロセスに戻される。
サービスマネージャーに渡されたファイル記述子は POLLHUP
または POLLERR
が表示されたとき、またはサービスが完全に停止していて、ジョブがキューに入れられていないか実行されていないときに、自動的に閉じられる。
このオプションを使用する場合は NotifyAccess=を設定して、 systemd が提供する通知ソケットへのアクセスを開く必要がある。
NotifyAccess= が設定されていない場合、暗黙的に main に設定される。
USBFunctionDescriptors=
USB ガジェット機能を実装するために USB FunctionFS 記述子を含むファイルの場所を設定。
これは ListenUSBFunction=
が設定されたソケットユニットとの組み合わせでのみ使用される。
このファイルの内容は、開いた後に ep0
ファイルに書き込まれる。
USBFunctionStrings=
USB FunctionFS 文字列を含むファイルの場所を構成する。
動作は上記の USBFunctionDescriptors= に類似。
その他の設定については systemd.exec(5) と systemd.kill(5) を確認。
コマンド行
このセクションでは以下のオプションのコマンド行解析と変数および指定子の置換について説明する。
複数のコマンド行はセミコロンで区切ることによって 1 つのディレクティブに連結できる(これらのセミコロンは別の単語として渡す必要がある)。
単一のセミコロンは \;
としてエスケープ。
各コマンド行は空白で分割される。
最初の項目は実行するコマンドであり、後続の項目は引数。
二重引用符( "..."
)と単一引用符( '...'
)は、アイテム全体をラップするために使用可能。
(開始引用符は引用符で囲まれていない空白の最初または後にのみ表示でき、終了引用符は空白または行末が後に続く)
この場合、次の一致する引用符までのすべてが同じ引数の一部となり、引用符自体は削除。
C スタイルのエスケープもサポートされてる。
以下の表に、既知のエスケープパターンのリストを示す。
表の構文に一致するエスケープパターンのみが許可される。
他のパターンが将来追加される可能性もあり、不明なパターンは警告になる。
特に、バックスラッシュは二重に記述する必要。
行末にバックスラッシュ( \
)を使用して行をマージできる。
この構文はシェル構文に影響を受けているが、以下で説明されているメタ文字と展開のみが解釈され、変数展開は異なる。
具体的には <
, <<
, >
, >>
を使用したリダイレクト、 |
を使用したパイプ、 &
を使用したバックグラウンドでのプログラムの実行、そしてシェル構文の他の要素はサポートされない。
実行するコマンドにスペースが含まれている可能性があるが、制御文字は使用できない。
systemd.unit(5) で説明されているように、コマンド行は %
指定子を受け入れる。
基本的な環境変数の置換をサポート。
コマンド行で ${FOO}
を単語の一部として、または単独の単語として使用する場合、${FOO}
は環境変数の値(空白を含む)に置き換えられ、空白で分割された環境変数の値に置き換えられ、 0 個以上の引数が生成され、単一の引数に変換される。
コマンド行で $FOO
を別の単語として使用する場合、
単語に分割するときに引用符が優先され、その後、削除。
コマンドがフル(絶対)パスではない場合、コンパイル時に決定された固定の検索パスを使用してフルパスに解決される。
検索されるディレクトリには /usr/bin/
と /bin/
ディレクトリを使用するシステムの /usr/local/bin/
, /usr/bin/
, /bin/
と、 bin/
, sbin/
を使用するシステムの、対応する sbin/
が含まれる。
したがって、「標準」ディレクトリのいずれかにある実行可能ファイルの場合は実行可能ファイル名だけを使用しても安全であり、標準ディレクトリにない場合は絶対パスを使用する必要がある。
あいまいさを避けるために、絶対パスを使用することをお勧めする。
ヒント: この検索パスは systemd-path search-binaries-default
を使用して照会される。
Environment="ONE=one" 'TWO=two two'
ExecStart=echo $ONE $TWO ${TWO}
この例では /bin/echo
に 4 つの引数を付与して実行する
- one
- two
- two
- two two
Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
ExecStart=/bin/echo $ONE $TWO $THREE
これにより /bin/echo
が 2 回呼び出され、最初は引数 'one'
, 'two two' too
, ""
で 2 回呼び出され、
2 回目は引数 one
, two two
, too
で呼び出される。
文字通りのドル記号を渡すには、 $$
を使用する。
展開時に値が不明な変数は、空の文字列として扱われる。
最初の引数(つまり、実行するプログラム)は変数ではない場合があることに注意!
この方法で使用される変数は Environment=
と EnvironmentFile=
で定義できる。
また systemd.exec(5) の「生成されたプロセスの環境変数」セクションに列記されている「静的構成」と見なされる変数を使用できる(これには $USER
は含まれるが $TERM
は含まれない)。
シェルコマンドラインは直接サポートされていないことに注意すること。
シェルコマンドラインを使用する場合は、何らかのシェル実装に明示的に渡す必要がある。
ExecStart=sh -c 'dmesg | tac'
ExecStart=echo one ; echo "two two"
これにより echo が 2 回実行され、そのたびに 1 つの引数がそれぞれ one
と two two
で実行される。
2 つのコマンドが指定されているため Type=oneshot
を使用する必要。
ExecStart=echo / >/dev/null & \; \
ls
この例では echo に 5 つの引数を付与して実行する
/
>/dev/null
&
;
ls
表3. コマンド行と環境変数でサポートされる C エスケープ
リテラル | 実際の値 |
---|---|
\a |
bell |
\b |
backspace |
\f |
form feed |
\n |
newline |
\r |
carriage return |
\t |
tab |
\v |
vertical tab |
\\ |
backslash |
\" |
二重引用符 |
\' |
引用符 |
\s |
space |
\xxx |
16進エンコードの文字番号xx |
\nnn |
8進エンコーディングの文字番号nnn |
記述例
例1. Type=simple
であるサービス
次のユニットファイルは /usr/sbin/foo-daemon
を実行するサービスを作成する。
Type= が指定されていないため、デフォルトの Type=simple
が想定される。
systemd は、プログラムの実行が開始された直後にユニットが起動すると想定する。
[Unit]
Description=Foo
[Service]
ExecStart=/usr/sbin/foo-daemon
[Install]
WantedBy=multi-user.target
この例では systemd は、 systemd によって開始されたプロセスがサービス終了まで存在し続けると想定していることに注意。
プログラムが自身をデーモン化する場合(フォークなど)、代わりに Type=forking
を使用する。
ExecStop= が指定されていないため systemd はこのサービスから開始されたすべてのプロセスに SIGTERM
を送信し、タイムアウト後も SIGKILL
を送信する。
この動作は変更が可能。
詳細については systemd.kill(5) を参照。
このユニットタイプには、サービスの初期化が完了したときの通知は含まれない。
サービスが systemd の通知プロトコルを理解する場合は Type=notify
、サービスがそれ自体をバックグラウンドで処理できる場合は Type=forking
、初期化が完了してユニットが DBus 名を取得する場合は Type=dbus
など、他のユニットタイプを使用する必要がある。
下記を参照。
例2. Type=oneshot
であるサービス
ユニットは場合によっては、ファイルシステムチェックや起動時のクリーンアップアクションなど、アクティブなプロセスを維持せずにアクションを実行する必要がある。
そのような場合に備えて Type=oneshot
が存在。
このタイプのユニットは指定されたプロセスが終了するまで待機してから、非アクティブにフォールバックする。
次のユニットは、クリーンアップアクションを実行する:
[Unit]
Description=Cleanup old Foo data
[Service]
Type=oneshot
ExecStart=/usr/sbin/foo-cleanup
[Install]
WantedBy=multi-user.target
systemd は、プログラムが終了するまでユニットを starting
の状態であると見なす。
そのため順序付けられた依存関係は、プログラムが終了してから開始する。
ユニットは実行が完了すると inactive
状態に戻り、 active
状態になることはない。
つまり、ユニットを起動するための別の要求がアクションを再度実行する。
Type=oneshot
は複数の ExecStart= が指定されている可能性がある唯一のサービスユニット。
それらは、すべてが成功するか、いずれかが失敗するまで順番に実行される。
例3. 停止可能な oneshot サービス
oneshot サービスと同様に、プログラムを実行して何かを設定してから別のプログラムを実行してシャットダウンする必要があるユニットがあるが、 started
と見なされている間、プロセスはアクティブのままである。
ネットワーク構成はこのカテゴリに分類される場合がある。
もう 1 つの使用例は、 oneshot サービスが依存関係として呼び出される時に実行されず、初めて実行される場合である。
このため systemd は設定 RemainAfterExit=yes
を参照する。
これにより、開始アクションが正常に終了した場合、 systemd はユニットがアクティブであると見なす。
このディレクティブはすべてのタイプで使用できるが、 Type=oneshot
と Type=simple
で最も役立つ。Type=oneshot
の場合、 systemd はユニットがアクティブであると見なす前に開始アクションが完了するまで待機するため、依存関係は開始アクションが成功した後にのみ開始。Type=simple
の場合、開始アクションがディスパッチされた直後に依存関係が開始される。
以下に単純な静的ファイアウォールの例を示す。
[Unit]
Description=Simple firewall
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/simple-firewall-start
ExecStop=/usr/local/sbin/simple-firewall-stop
[Install]
WantedBy=multi-user.target
開始アクションが終了した後、ユニットは実行中と見なされるため、そのユニットで systemctl start
を再度呼び出しても、アクションは実行されない。
例4. 伝統的な forking サービス
多くの伝統的なデーモン / サービスのバックグラウンド(つまり fork
, daemonize
)は、起動時に自分自身をバックグラウンドで実行する。
この操作モードをサポートするには、サービスのユニットファイルで Type=forking
を設定する。
systemd は、元のプログラムがまだ実行されている間、サービスが初期化のプロセスにあると見なす。
正常に終了し、少なくともプロセスが残っている場合(または RemainAfterExit=no
)、サービスは開始されていると見なされる。
多くの場合、伝統的なデーモンは 1 つのプロセスのみで構成されている。
したがって、元のプロセスが終了した後に 1 つのプロセスしか残っていない場合、 systemd はそのプロセスをサービスのメインプロセスと見なす。
その場合 $MAINPID
変数は ExecReload= , ExecStop= などで使用可能。
複数のプロセスが残っている場合、 systemd はメインプロセスを判別できないため、メインプロセスがあると想定しない。
その場合 $MAINPID
は展開されません。
ただし、プロセスが伝統的な PID ファイルを書き込むことを決定した場合、 systemd はそこからメイン PID を読み取ることができる。
PIDFile= を適宜設定する。
デーモンは初期化を完了する前に PID ファイルを書き込む必要があることに注意!。
そうしないと systemd は PID ファイルが生成される前にファイルを読み取ろうとする場合がある。
次の例は、バックグラウンドで 1 つのプロセスを分岐して開始する単純なデーモンを示す:
[Unit]
Description=Some simple daemon
[Service]
Type=forking
ExecStart=/usr/sbin/my-simple-daemon -d
[Install]
WantedBy=multi-user.target
systemd がサービスを終了する方法に影響を与える方法の詳細については systemd.kill(5) を参照。
例5. dbus サービス
DBus システムバスで名前を取得するサービスの場合は、 Type=dbus
を使用し、対応する BusName= を設定する。
サービスはフォーク(デーモン化)すべきではありません。
systemd は、システムバスで名前が取得されると、サービスが初期化されたと見なす。
次の例は、典型的な DBus サービスを示す。
[Unit]
Description=Simple DBus service
[Service]
Type=dbus
BusName=org.example.simple-dbus-service
ExecStart=/usr/sbin/simple-dbus-service
[Install]
WantedBy=multi-user.target
バスでアクティブ化可能なサービスの場合、 systemd サービスファイルに [Install]
セクションを含めないこと。
代わりに対応する DBus サービスファイルで SystemdService=
オプションを使用する。
example (/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):
[D-BUS Service]
Name=org.example.simple-dbus-service
Exec=/usr/sbin/simple-dbus-service
User=root
SystemdService=simple-dbus-service.service
systemd がサービスを終了する方法に影響を与える方法の詳細については systemd.kill(5) を参照。
例6. 初期化について systemd に通知するサービス
Type=simple
のサービスは非常に簡単に記述できるが、 systemd が特定のサービスの初期化が完了したことを通知できないという大きな欠点がある。
このため systemd は、デーモンが systemd に初期化が完了したことを認識させる簡単な通知プロトコルをサポート。
これには Type=notify
を使用。
このようなデーモンの典型的なサービスファイルを以下に示す:
[Unit]
Description=Simple notifying service
[Service]
Type=notify
ExecStart=/usr/sbin/simple-notifying-service
[Install]
WantedBy=multi-user.target
デーモンは systemd の通知プロトコルをサポートする必要があることに注意して。
そうでない場合 systemd はサービスがまだ開始されていないと見なし、タイムアウト後にサービスを強制終了する。
このプロトコルを透過的にサポートするようにデーモンを更新する方法については、 sd_notify(3) を参照。
systemd は、準備完了通知が到着するまで、ユニットが starting
状態にあると見なす。
systemd がサービスを終了する方法に影響を与える方法の詳細については systemd.kill(5) を参照。