こんにちは、masm11 です。
前回から始まった systemd シリーズ。今回は .service
ファイルの書き方です。
.service
ファイルとは
このファイルにサービスの定義を記述します。
sysvinit 等であれば /etc/init.d/
や /etc/rc.d/
に置いていた script の代わりとなるものです。
ファイルの置き場所としては、OS のパッケージに含まれる場合は
/usr/lib/systemd/system/
や /lib/systemd/system/
にある場合が多いと思いますが、
自分で作る場合は /etc/systemd/system/
に置きます。
[Unit]
部分
.service
ファイルは、まず [Unit]
という行から始まります。
[Unit]
部分は以下のような感じになっています。
[Unit] Description=ZFS replication service After=network.target Requires=network.target
Description
はこのサービスの説明です。あまりたいした意味はないのですが、
以下のように、ログに出力される時などに使われます。
10月 08 02:00:00 luna systemd[1]: Started ZFS replication service.
After
や Requires
は依存関係を記述します。
Requires
を書いておくと、network.target が起動に失敗した場合は
この unit は起動しなくなります。
依存関係を記述する方法は、他にも Wants
や Conflicts
などいろいろありますが、
After
と Requires
を使っていればわりとなんとかなっています。
[Service]
部分
.service
ファイルには [Service]
部分があります。
以下のような感じになっています。
[Service] Type=oneshot RemainAfterExit=yes ExecStart=/etc/systemd/lo-setup start ExecStop=/etc/systemd/lo-setup stop
Type
simple
, exec
, forking
, oneshot
, dbus
, notify
, idle
の
中から選択して指定します。よく使うのは oneshot
, simple
, forking
です。
oneshot
: 一度実行してすぐ終了するタイプに指定します。simple
: デフォルトです。 起動したプロセスがサービスを提供する場合に指定します。fork
: 起動したプロセスが起動時に fork する場合に指定します。
ExecStart
/ ExecStop
/ ExecStartPre
ExecStart
は systemctl start
した時に実行するコマンドを指定します。
ExecStop
は systemctl stop
した時にサービスを停止するコマンドを指定します。
省略することもよくあります。省略した場合は systemd がプロセスにシグナルを
送って止めます。
ExecStartPre
は ExecStart
の前に実行しておきたいコマンドを指定します。
ExecStartPre
は複数指定することができます。
マニュアルには
If the command is not a full (absolute) path, it will be resolved to a full path using a fixed search path determinted at compilation time.
と、コマンドがフルパスでなくても大丈夫そうなことが書いてありますが、 経験的にはフルパスでないと動いてくれません。
コマンドの前に -
を書いておくと、エラーを無視してくれるようです。
ExecStartPre
でちょっと先に実行しておきたいけど、エラーになる場合もある、
というような場合に便利そうです。
RemainAfterExit
RemainAfterExit=yes
と指定しておくと、プロセスが終了しても、異常扱いになりません。
Restart
/ RestartSec
Restart=always
と指定しておくと、プロセスが終了した場合に、もう一度起動してくれます。
ただ、すぐに起動してしまうので、間隔をあけたい場合は、追加で
RestartSec=5
と指定しておけば、5秒待ってくれます。
User
プロセスのユーザを指定します。
User=masm
聞くところによると、存在しないユーザを指定すると root になってしまう
仕様だそうです。User
を指定する際にはご注意ください。
StandardOutput
/ StandardError
これらは、プロセスの標準出力と標準エラー出力をどうするかを指定します。
私は大抵 journal
と指定しています。この場合、systemd の journal に
出力され、journalctl コマンドで見ることができます。
他にも、ファイルへ出力したり、tty に出力したり、いろいろな指定ができるようです。
[Install]
部分
これを書いておくと、systemctl enable
できるようになります。
[Install] WantedBy=multi-user.target
multi-user で起動する際には、この .service
も start する、
という指定です。
大抵の場合は multi-user.target
で大丈夫です。
@
と %i
.service
ファイルのファイル名に @
を含めることができます。
例えば zfsnap@.service
という感じです。
この場合、systemctl enable
や systemctl start
の際には、
systemctl start zfsnap@2w.service
というように指定します。@
の後ろに 2w
と付けました。
この 2w
は .service
ファイルの中で、%i
を使って受け取れます。
具体的には以下のように使います。
[Service] Type=oneshot ExecStart=/usr/bin/zfsnap snapshot -a %i zbak/android zbak/svc zbak/tama
この場合だと、%i
が 2w
に置き換わって、
/usr/bin/zfsnap snapshot -a 2w zbak/android zbak/svc zbak/tama
が実行されるわけです。
この zfsnap@.service
ファイル一つで、zfsnap@2w.service
, zfsnap@3d.service
など
いろんな使い方ができます。
あまり使わないですが、たまに便利なことがある機能です。
まとめ
今回は .service
ファイルの書き方を経験を交えながら淡々と説明しました。
前回同様、私が使うものだけに絞っています。
.service
ファイルはそれだけで使うこともできますが、
他の unit ファイルと組み合わせて使うこともできる、便利なものです。
組み合わせ方は次々回以降に説明しますのでご期待下さい。
ではまた!