はじめに

先日、自作のデスクトップマシンで使っていた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にはパッケージが用意されていると思いますので、各々のOSの方法に従い導入してください。

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

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

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

ということで、お試し下さい。


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

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

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

ご注意

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


まさにこれだ
3 (100%)

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