Linux でシステムのフリーズを検知して自動的に再起動させる方法
はじめに
我が家の Raspberry Pi が定期的にフリーズするのですが、原因が全くわかません。
何か対応策はないものかと調べていたら、Linux には Watchdog timer という仕組みがあることがわかりました。
今回は Ubuntu 22.04.1 LTS をインストールした Raspberry Pi で Watchdog timer を有効にして、システムフリーズ時に自動的に再起動するようにしてみます。
基本的には Raspberry Pi & Ubuntu でなくても、Linux をインストールしたマシンなら同じ方法で設定できると思いますので、ぜひ参考にしてみてください。
Watchdog timer の有効化
まずは Watchdog timer を有効にします。
/boot/config.txt
に以下の 1 行を追加します。このファイルを今までに作ったことがない場合はファイルを新規作成します。
dtparam=watchdog=on
Heartbeat の設定
Heartbeat は日本語に訳すと心臓の鼓動で、システムが正常に動作しているかどうかの確認を一定間隔ごとに行うものです。後述する設定で、このハートビートが一定期間以上なかった場合は再起動するようにします。
/etc/systemd/system.conf.d/main.conf
というファイルを作成し、以下の 1 行を追加します[1][2]。/etc/systemd/system.conf.d/
ディレクトリがない場合は作成します。
[Manager]
RuntimeWatchdogSec=5
上記の設定で、5 秒ごとに Heartbeat を行います。
再起動のしきい値の設定
先ほど設定した Heartbeat が一定期間以上来なかったら再起動する設定を行います。
/etc/modprobe.d/bcm2835-wdt.conf
に以下の 1 行を追加します。ファイルがない場合は新規作成します。
options bcm2835_wdt heartbeat=10 nowayout=0
上記の設定で、10 秒以上 Heartbeat が来なかった場合は再起動するようにします。
再起動
システムを再起動して設定を反映させます。
sudo reboot
起動しているか確認
ログを見て Watchdog timer が起動しているか確認します。
まずは以下のコマンドを実行します。
sudo dmesg | grep bcm2835-wdt
以下のような出力があれば OK です。
[ 1.949143] bcm2835-wdt bcm2835-wdt: Broadcom BCM2835 watchdog timer
次に以下のコマンドを実行します。
sudo dmesg | grep systemd | grep watchdog
以下のような出力がされれば OK です。
[ 9.389119] systemd[1]: Using hardware watchdog 'Broadcom BCM2835 Watchdog timer', version 0, device /dev/watchdog
[ 9.401138] systemd[1]: Set hardware watchdog to 5s.
動作確認
本当にフリーズしたときに再起動するのか試してみます。
フリーズさせる方法はいろいろありますが、代表的な方法として フォーク爆弾 を投下してみます。以下のコマンド[3]を実行します。
:(){ :|:& };:
実行後、シェルが急激に重くなります。
数分待って、システムが自動的に再起動されれば成功です。
さいごに
これはあくまで応急処置であって、本当はシステムが頻繁にフリーズする原因を突き止めるのが得策です。
でも、システムのフリーズなどという漠然とした問題の原因を突き止めるのは容易ではないですし、それなりに時間もかかります。Watchdog timer は根本原因解決までの代替手段としては有効かなと思います。
あるいは、このような問題がなかったとしても、何が起こるかはわからないので、盤石な構成にしておくという意味で有効にするのはありかなと思います。
参考
- ラズパイが2~3日でフリーズするのでウォッチドッグタイマーを設定して回避した
- ラズパイ安定化対策-フリーズ対応編
- 【WatchDogTimer】Raspberry Pi4サーバがフリーズ(停止)した場合に自動再起動する方法【HeartBeat】
Discussion