Armadilloフォーラム

systemd.serviceを利用したWDT監視の動作について

masaya_yoshitomi

2024年7月8日 20時45分

------------------------------------------------------------------------------------
■環境
------------------------------------------------------------------------------------

【動作環境】
 ・OS:Debian GNU/Linux 10 (buster)
 ・Boot:u-boot-x1-at23.bin
 ・カーネル:uImage-x1-v4.9-at26
 ・DTB:armadillo_iotg_g3_m1-v4.9-at26.dtb
 ・ファイルシステム:debian-buster-armhf_aiotg3_20221118.tar.gz(fixupにて独自変更を加えています)

------------------------------------------------------------------------------------
■質問の背景
------------------------------------------------------------------------------------
独自で作成したアプリケーションをsystemdにサービス登録したうえで、
systemdのウォッチドッグ機能を使用してアプリケーションを監視しています。

プロセスを起動後に、Terminalからdateコマンドにてシステム時間を過去時間に設定すると
頻繁にsystemdによるWDTを検出し同軸で作成したアプリケーションが再起動します。

------------------------------------------------------------------------------------
■質問
------------------------------------------------------------------------------------
前述の通りdateコマンドでシステム時刻を過去時間に設定するとWDTを頻繁に検出するのですが、
systemdの仕組みとして、WDTを誤検出する可能性はないでしょうか?
※起動時の過程で一度nictとNTPの同期を行っています。その後手動でTerminalからdateコマンドにて
過去時間に手動で変更しております。

以下一部抜粋にはなりますが、サービスの設定ファイルの内容になります。
WDTの監視は1秒にしております。

/etc/systemd/system/xxxx.service
※xxxxはプロセスの名称です。

-----
[Service]
Type=simple
ExecStart=/usr/bin/XXXX
ExecStartPre=timedatectl set-ntp no
RestartSec=5
WatchdogSec=1
-----

コメント

at_shinya.koga

2024年7月9日 10時28分

アットマークテクノの古賀です。

masaya_yoshitomiさん:
>前述の通りdateコマンドでシステム時刻を過去時間に設定するとWDTを頻繁に検出するのですが、
>systemdの仕組みとして、WDTを誤検出する可能性はないでしょうか?
>※起動時の過程で一度nictとNTPの同期を行っています。その後手動でTerminalからdateコマンドにて
> 過去時間に手動で変更しております。

監視対象サービスが sd_notify() を呼び出す間隔と、WatchdogSec に指定した秒数の兼ね合いにより、実際にはサービスが動作継続していても system の WDT 動作が発動する可能性があると思います。
監視対象サービスが、起動してから最初に sd_notify() を呼び出すまでの時間が、他のプロセスの動作状況により WatchdogSec に指定した秒数よりも長くかかった場合にも、system の WDT 動作が発動するはずですよね。

>以下一部抜粋にはなりますが、サービスの設定ファイルの内容になります。
>WDTの監視は1秒にしております。
>
>/etc/systemd/system/xxxx.service
>※xxxxはプロセスの名称です。
>
>-----
>[Service]
>Type=simple
>ExecStart=/usr/bin/XXXX
>ExecStartPre=timedatectl set-ntp no
>RestartSec=5
>WatchdogSec=1
>-----

WatchdogSet の秒数を、たとえば倍の2にした場合に状況が少し改善するようであれば、この値を大きくすることを検討されるのが良いかも知れません。その場合、監視対象サービスが sd_notify() を呼び出すときにログ出力して記録するなどして、呼び出し間隔を実測して分析すれば、より適切な値を導出できるかと思います。
いかがでしょうか?

masaya_yoshitomi

2024年7月9日 16時06分

古賀様

回答ありがとうございます。
WatchdogSecを変更しても改善されず発生します。120secにしてもWDTは発生しました。
弊社で作り込んでいるアプリケーション部が主要因である可能性はもちろんあるので、その観点では調査進めるのですが、その他で何か調査の切り口はありませんでしょうか。。。
アドバイスいただけると幸いです。

at_shinya.koga

2024年7月9日 17時27分

アットマークテクノの古賀です。

masaya_yoshitomiさん:
>回答ありがとうございます。
>WatchdogSecを変更しても改善されず発生します。120secにしてもWDTは発生しました。

ご確認有り難うございます。ということであれば、systemd に要因がありそうですね。

>弊社で作り込んでいるアプリケーション部が主要因である可能性はもちろんあるので、その観点では調査進めるのですが、その他で何か調査の切り口はありませんでしょうか。。。
>アドバイスいただけると幸いです。

発生要因は、最初の質問で書いていらしたように、date コマンドでシステム時間を過去時間に変更する、ということですね:

masaya_yoshitomiさん(2024年7月8日 20時45分):
>------------------------------------------------------------------------------------
>■質問の背景
>------------------------------------------------------------------------------------
>独自で作成したアプリケーションをsystemdにサービス登録したうえで、
>systemdのウォッチドッグ機能を使用してアプリケーションを監視しています。
>
>プロセスを起動後に、Terminalからdateコマンドにてシステム時間を過去時間に設定すると
>頻繁にsystemdによるWDTを検出し同軸で作成したアプリケーションが再起動します。

とすると、systemd のタイマー設定動作に要因があるのかも知れません。
この件と同じ要因なのかどうか分かりませんが、システム日時を変更した時の system の挙動について、2017年から Open したままの issue があるようです:
 https://github.com/systemd/systemd/issues/6036
この issue に対しては、修正が試みられたものの、差し戻しになっているようです:
 https://github.com/systemd/systemd/pull/24131

試しに、ですが、次のようにすると、どうなるでしょうか?

1.) /etc/systemd/system/xxxx.service の内容を変更して、WatchdogSec の値を 0 (: 無効)にする。

2.) 'sudo systemctl daemon-reload' を実行する。

3.) date コマンドでシステム時間を過去時間に変更する。

4.) /etc/systemd/system/xxxx.service の内容を再度変更して、WatchdogSec の値を所望の値に戻す。

5.) 'sudo systemctl daemon-reload' を実行する。

masaya_yoshitomi

2024年7月9日 18時07分

> 試しに、ですが、次のようにすると、どうなるでしょうか?
>
> 1.) /etc/systemd/system/xxxx.service の内容を変更して、WatchdogSec の値を 0 (: 無効)にする。
>
> 2.) 'sudo systemctl daemon-reload' を実行する。
>
> 3.) date コマンドでシステム時間を過去時間に変更する。
>
> 4.) /etc/systemd/system/xxxx.service の内容を再度変更して、WatchdogSec の値を所望の値に戻す。
>
> 5.) 'sudo systemctl daemon-reload' を実行する。

上記は何を確認するための手順か目的を教えていただけますでしょうか。
すでに以下手順でWDTが発生することは確認できております。
1.xxxx.seriviceのWatchdogSec の行を削除
2.systemctl restart xxxx.service
3.dateで過去時間へ変更 ※しばらく放置するとWDT発生

また"sudo systemctl daemon-reload"を実行すると動作中のxxxx.serviceに設定がリアルタイムで反映されるのでしょうか?
serviceの再起動が必要と認識しておりましたので念のための確認となります。
servic再起動が必要と思っていましたので上記の5ステップの目的がわからず上記の質問となっております。
ご回答のほどお願いいたします。

at_shinya.koga

2024年7月9日 18時44分

アットマークテクノの古賀です。

masaya_yoshitomiさん:
>>試しに、ですが、次のようにすると、どうなるでしょうか?
>>
>>1.) /etc/systemd/system/xxxx.service の内容を変更して、WatchdogSec の値を 0 (: 無効)にする。
>>
>>2.) 'sudo systemctl daemon-reload' を実行する。
...
>上記は何を確認するための手順か目的を教えていただけますでしょうか。

systemctl daemon-reload を実行することにより、systemd の service manager に unit の設定変更をリロードさせてタイムアウト時間を再計算させられないかという確認です。

>すでに以下手順でWDTが発生することは確認できております。
>1.xxxx.seriviceのWatchdogSec の行を削除
>2.systemctl restart xxxx.service
>3.dateで過去時間へ変更 ※しばらく放置するとWDT発生

systemctl restart の場合は、再起動を指定したサービス自身が解釈する設定内容しか変更されないのではないかと思い、systemctl daemon-reload を試してみてください、と書いた次第です:
 https://qiita.com/sinsengumi/items/24d726ec6c761fc75cc9
 https://man7.org/linux/man-pages/man1/systemctl.1.html

実際に効果があるかどうかは、分かりません。
が、sd_watchdog_enabled() などのマニュアルを見ても、systemd に WDT 動作を一旦止めさせて再開する API が無さそうなので、systemctl daemono-reload が使えないかな、と思ったわけです。が、実際に試してはいませんので、効果があるかどうかは分かりません。

>また"sudo systemctl daemon-reload"を実行すると動作中のxxxx.serviceに設定がリアルタイムで反映されるのでしょうか?
>serviceの再起動が必要と認識しておりましたので念のための確認となります。
>servic再起動が必要と思っていましたので上記の5ステップの目的がわからず上記の質問となっております。
>ご回答のほどお願いいたします。

ということで、systemd による WDT 監視対象のサービス自身ではなく、監視している systemd の service manager 機能に設定変更を反映させるのに systemctl daemono-reload が使えないか試してみてください、ということです。いかがでしょうか?