SMARTの出力値からHDDの故障を予測する(smartctl)

対象プラットフォーム: FreeBSD 10.x
(下記手順を2017/06/20にFreeBSD 10.3-RELEASEで確認済み)


はじめに

先日、自作のデスクトップマシンで使っていたHDDがお亡くなりになった。
起動させようとすると、アクセスランプがつきっぱなしになってしまい、認識しなくなってしまう。

おそらく不良セクタの代替処理などをしているのだろう、しばらく放置してからマシンを再起動するとHDDは認識される。
だが、再度認識できたHDDでは、ファイルの欠損などが発生しており、もはやこれ以上の利用は危険である。

データについては、週次でバックアップを取っていたので、新しいHDDに交換し、バックアップからデータを復元して事無きを得たが、またいつこのような事態に遭遇するかわからない。

今回のようなHDDの故障を事前に予測することはできないのだろうか?

SMARTの出力とHDD故障の因果関係

HDDの故障予測といえば、SMARTが有名である。
Googleが2007年に出した論文によると、SMARTですべてのHDDの故障を事前に予知することは不可能だが、SMARTの値のうち、以下の数値には相関関係があるとのこと。

1 Raw_Read_Error_Rate
→ 危険水域は、この値が1以上になった時。
0の時に比べ、60日後の故障確率は39倍になる。

5 Reallocated_Sector_Ct
196 Reallocated_Event_Count
198 Offline_Uncorrectable
→ 危険水域は、この値が1以上になった時。
0の時に比べ、60日後の故障確率は14倍になる。

197 Current_Pending_Sector
→ 危険水域は、この値が1以上になった時。
0の時に比べ、60日後の故障確率は16倍になる。

すべての故障の予知は無理でも、事前に予知できる場合があるなら、これを使わない手はないだろう。
これらの値をPCの起動時などに定期的に監視し、値が変わった場合に警告を出すような仕組みを作れば、万全ではないもののHDDの故障をある程度の確率で予測することができるはずだ。

監視用シェルスクリプトの作成

ということで、上記のSMARTの値を監視するシェルスクリプトを作成してみた。
(FreeBSD向けに記述したが、Vine Linuxでも動作したので、他のLinux環境でもさほど手を入れずに利用可能と思われる。)

SMART値の監視用シェルスクリプト
#!/bin/sh

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
export PATH

target_disk='/dev/ad0'
mail_to='hoo@bar'

smartctl_output='/tmp/smartctl_output.txt'
monitor_current='/var/tmp/smartctl_monitor_new.txt'
monitor_previous='/var/tmp/smartctl_monitor_old.txt'
monitor_difference='/tmp/smartctl_diff.txt'

mailqueue_file=''

if  [ -e ${monitor_previous} ]
then
	rm ${monitor_previous}
fi

if  [ -e ${monitor_current} ]
then
	mv ${monitor_current} ${monitor_previous}
fi

smartctl -x ${target_disk} > ${smartctl_output}

cat ${smartctl_output} | grep Raw_Read_Error_Rate     >  ${monitor_current}
cat ${smartctl_output} | grep Reallocated_Sector_Ct   >> ${monitor_current}
cat ${smartctl_output} | grep Reallocated_Event_Count >> ${monitor_current}
cat ${smartctl_output} | grep Current_Pending_Sector  >> ${monitor_current}
cat ${smartctl_output} | grep Offline_Uncorrectable   >> ${monitor_current}

rm ${smartctl_output}

if  [ -e ${monitor_previous} ]
then 
	diff ${monitor_current} ${monitor_previous} > ${monitor_difference}
fi

if [ -s ${monitor_difference} ]
then
	mail_title="[ALERT] SMART indicator(s) varied : ${target_disk} at `hostname`"

	if [ -z ${mailqueue_file} ]
	then
		cat ${monitor_current} | mail -s "${mail_title}" ${mail_to}
	else
		echo "From: smart-value-checker@`hostname`" > ${mailqueue_file}
		echo "To: ${mail_to}" >> ${mailqueue_file}
		echo "Subject: ${mail_title}" >> ${mailqueue_file}
		printf "\r\n" >> ${mailqueue_file}
		cat ${monitor_current} >> ${mailqueue_file}
	fi
fi

if [ -e ${monitor_difference} ]
then
	rm ${monitor_difference}
fi

自分の環境に合わせて以下の箇所を変更する。

要設定変更箇所
	target_disk='/dev/ad0'
	mail_to='hoo@bar'

SMARTの値の取得は、smartctlを使っており、事前の準備としてこれを導入する必要がある。
処理系にもよるが、たいていのOSにはパッケージが用意されている。

FreeBSDでは、pkgかportsから「ports/sysutils/smartmontool」を導入すればよいし、Vine Linuxでは、Synapticパッケージマネージャを使って「smartmontool」を導入すればよい。

やっていることは至極単純で、smartctlの出力のうち、該当箇所を抜き出してファイルに保存、それを前回保存したファイルと比較し、異なっているようなら指定したアドレスにメールを送信するだけ。
直接メール送信できない処理系の為に、メールキューにファイルを置くこともできる。
その際は「mailqueue_file='/root/mail/queue/mail.txt'」の様に書き出し先のファイル名を指定する。

PC起動時にこのチェックを実行したり(crontabの@rebootで実現可能)、常時起動のサーバで1日に1回など、定期的に実行したい場合にはcronを使えばよい。
このシェルスクリプトをシステムに仕掛けておけば、自らが能動的にSMARTの値をチェックし続けなくても、値に変化があれば警告メールを受け取ることができる。

ということで、お試しあれ。


あなたの探し物は見つかりましたか?
まさにこれだ
参考になった
ちょっと違う
これじゃない

何かメッセージがあればお願いします

このメッセージを非公開にする

ご注意

・頂いたメッセージは管理者のチェックの後、公開されます。
・メッセージの公開を希望されない場合には、「このメッセージを非公開にする」にチェックを入れてください。
・管理者が不適切と判断したメッセージは公開しませんので、予めご了承ください。


まだ評価がありません

表示できるメッセージはありません。


目次に戻る
image