🔖

[systemd]ExecStopが勝手に起動する?一度Typeを見直してみよう

2021/05/27に公開

概要

Minecraftのサーバーを立ててservice化するために、以下のようにユニットファイルを書きました。

[Unit]
Description=Minecraft Server
After=network.target

[Service]
ExecStart=/home/username/minecraft/start.sh
ExecStop=/home/username/minecraft/stop.sh
Restart=always
Type=symple
WorkingDirectory=/home/username/minecraft/
User=ubuntu
Group=ubuntu

[Install]
WantedBy=multi-user.target

start.shは以下のようになっています。
minecraftという名前のscreenでMinecraftを起動しています。

#!/bin/sh

cd `dirname $0`
screen -UAmdS minecraft java -server -Xms4096M -Xmx4096M -jar server.jar nogui

stop.shではscreenにアタッチしてから10秒待ってsave-allとstopを実行しています。
この状態でsudo systemctl start minecraftしたところ、以下のようになりました。
(ログはjournalctl -e -u minecraftで出力しています)

May 26 14:22:22 myserver systemd[1]: Started Minecraft Server.
May 26 14:22:22 myserver stop.sh[826]: server stop script start
May 26 14:23:07 myserver systemd[1]: minecraft.service: Succeeded.
May 26 14:23:07 myserver systemd[1]: Stopped Minecraft Server.

スタートと同時にExecStopに指定したstop.shが起動してしまっています。

原因

ユニットファイルのType=simpleが原因でした。
Type=forkingにしたら動きました。

理由

ユニットファイルのTypeに指定できる値はいくつかありますが、そのうちデフォルト値のsimpleは、ExecStartで起動したプロセス自体を見るという指定になります。
上のstart.sh自体はscreenコマンドを実行したあと終了してしまいますから、サービス自体も終了したと見なされてExecStopが実行されてしまいます。
forkingにすると、ExecStartで起動したプロセスが終了し、その子プロセスがメインとなるため、正しく動作します。

Discussion