Linux
systemd

systemdの*.serviceファイルの書き方

More than 5 years have passed since last update.

たまに書く必要があったりするのでめも。環境はArch Linux。

まず基本的なところで前に自分で書いた/etc/systemd/system/kdump.serviceを元に。


kdump.service

[Unit]

Description=Load dump capture kernel
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/opt/bin/run-kexec.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target


ファイルの基本構成要素は UnitServiceInstall から成り立っていて UnitInstall はman 5 systemd.unit、 Service はman 5 systemd.serviceに詳細な説明があります。

UnitInstall はユニットファイルの共通的な設定内容、 Service はそのサービスを実行するためというような感じになってます。


Unitセクション


Description

ユニットの説明を書く。


After/Before

After(Beforeも)は指定したユニットの実行順番の依存関係を設定する。例えばfoo.serviceで↓のように書いていたらfoo.serviceはbar.serviceのstart-up処理が終わるまで起動しない。

After=bar.service


Requires/Wants

ユニットの依存関係の定義。RequiresとWantsの大きな違いとしてリストアップした依存関係のユニットが失敗したときの処理が違う。foo.serviceで↓のように書いた場合、bar.serviceの起動に失敗してもfoo.serviceのstartup処理そのものが失敗になる訳ではない(もちろんfoo.serviceを起動する上でbarが必要ならだめだけど)。

Wants=bar.service


その他

man 5 systemd.unit


Serviceセクション


Type

Typeには以下の5があり、設定がなければsimpleがデフォルトで使われる。


  • simple

  • forking

  • oneshot

  • notify

  • dbus

kdump.serviceの場合はoneshotを使っていて、これはコマンドとしてはすぐに終わるような場合に使う。


ExecStart

実行するコマンドラインを書く


RemainAfterExit

Typeがoneshotの場合はコマンドの実行終了後もステータスをアクティブにしておきたいのでRemainAfterExit=yesとしてsystemdにこのユニットはアクティブですよーと知らせる。


kdumpの例

kdumpの例だとTypeはoneshot、RemainAfterExitにyesを設定し、こんなスクリプトを実行してます。

#!/bin/bash

kernname=`uname -r`
boot_dir=/boot
vmlinuz="$boot_dir/vmlinuz-$kernname"
initramfs="$boot_dir/initramfs-$kernname.img"
root_dev=`cat /proc/cmdline | sed 's/ /\n/g' | grep ^root= | cut -f2- -d'='`

echo /usr/bin/kexec -p "$vmlinuz" --initrd="$initramfs" --append="root=$root_dev single irqpoll maxcpus=1 reset_devices"
/usr/bin/kexec -p "$vmlinuz" --initrd="$initramfs" --append="root=$root_dev single irqpoll maxcpus=1 reset_devices"
echo "kexec comman executed"

exit 0


sshdの例

sshdの場合はプロセスの再起動、終了なんかの設定も入ってます。

[Service]

ExecStart=/usr/bin/sshd -D
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always


その他

man 5 systemd.service


Installセクション


WantedBy/RequiredBy

systemctl enable XXXでユニットをenableしたときに.wants、.requiresにシンボリックリンクを作る。 動作としてはWants=、Requires=と同じような感じ。

実際にこんな感じになってます。

masami@saga:~$ ls -la /etc/systemd/system/multi-user.target.wants/

total 8
drwxr-xr-x 2 root root 4096 Dec 4 14:13 .
drwxr-xr-x 4 root root 4096 Dec 4 14:13 ..
lrwxrwxrwx 1 root root 38 Nov 1 01:53 dhcpcd.service -> /usr/lib/systemd/system/dhcpcd.service
lrwxrwxrwx 1 root root 33 Nov 5 12:14 kdump.service -> /etc/systemd/system/kdump.service
lrwxrwxrwx 1 root root 40 Nov 1 10:27 libvirtd.service -> /usr/lib/systemd/system/libvirtd.service
lrwxrwxrwx 1 root root 36 Dec 4 14:13 ntp-once.service -> /etc/systemd/system/ntp-once.service
lrwxrwxrwx 1 root root 40 Oct 21 22:27 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx 1 root root 36 Nov 1 07:45 sshd.service -> /usr/lib/systemd/system/sshd.service


その他

man 5 systemd.unit