Linux: systemdのstart request repeated too quickly for xxx.service

10秒以内に一つのサービスに対してsystemctl restart xxxを6回実行するとエラーが発生してサービスの起動に失敗する場合があります。この記事ではその回避策を記載します。

1 start request repeated too quickly for xxx.service

これはシステム起動時に問題が発生した場合に、サービスの再起動を繰り返すのを防ぐ為の処理です。

StartLimitIntervalの値で指定した時間以内にサービスの再起動がStartLimitBurstの値を超えた場合はサービスの起動を失敗させます。StartLimitIntervalのデフォルト値は10秒、StartLimitBurstのデフォルト値は5回です。

例えばdhcpdの場合は以下の通りです。6回目のsystemctl restart dhcpdでサービスの起動が失敗します。

$ i=1
$ while : ; do
  echo ${i}
  i=$(expr ${i} + 1);
  sudo systemctl restart dhcpd || break
done
1
2
3
4
5
6
Job for dhcpd.service failed because start of the service was
attempted too often. See "systemctl status dhcpd.service" and
"journalctl -xe" for details.
To force a start use "systemctl reset-failed dhcpd.service" followed
by "systemctl start dhcpd.service" again.

journalctlでログを確認すると問題のstart request repeated too quickly for dhcpd.serviceが表示されています。

$ sudo journalctl -xeu dhcpd
<snip>
systemd[1]: start request repeated too quickly for dhcpd.service
<snip>

2 systemctl reloadを使う

systemctl reloadを実行できるサービスの場合はそちらを使います。

$ systemctl show -p CanReload named
CanReload=yes

10秒以内にsystemctl reloadを6回以上実行してもエラーにはなりません。

$ sudo systemctl start named
$ i=1
$ while : ; do
  echo ${i}
  i=$(expr ${i} + 1);
  sudo systemctl restart named || break
done
1
2
3
4
5
6
7
8
<snip>

3 systemctl reloadが使えない場合はStartLimitBurst=0を使う

systemctl reloadを実行できないサービスもあります。dhcpdの場合はreloadの実装に手が回らないだけのようです。興味のある方はぜひ実装してください。

$ systemctl show -p CanReload dhcpd
CanReload=no

systemctl reloadを実行できないサービスの場合は、StartLimitBurstを0にすることで、再起動回数の判定を無効にします。ただし、起動時に再起動を繰り返す恐れのあるサービス以外に限ります。

以下のコマンドでsystemdのファイルを確認します。

$ systemctl show -p FragmentPath dhcpd
FragmentPath=/usr/lib/systemd/system/dhcpd.service

[Service]のセクションにStartLimitBurst=0を設定します。

$ diff -uprN /usr/lib/systemd/system/dhcpd.service{.org,}
--- /usr/lib/systemd/system/dhcpd.service.org   2017-02-17 10:57:45.657561554 -0500
+++ /usr/lib/systemd/system/dhcpd.service       2017-02-17 12:25:15.733977821 -0500
@@ -8,6 +8,7 @@ After=time-sync.target
 [Service]
 Type=notify
 ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid
+StartLimitBurst=0

 [Install]
 WantedBy=multi-user.target

systemdに変更したファイルを読み込ませます。

$ sudo systemctl daemon-reload

10秒以内にsystemctl restartを6回以上実行してもエラーにはなりません。

$ i=1
$ while : ; do
  echo ${i}
  i=$(expr ${i} + 1);
  sudo systemctl restart dhcpd || break
done
1
2
3
4
5
6
7
8
<snip>