アイドル状態のときにハードドライブをスピンダウンさせたいのですが、たとえば20分間です。このNASはめったに使用されないため、任意の分数で問題ありません。
私が試したがうまくいかなかったこと:
ataidle -S 20 /dev/ada0
は単にドライブをただちにスピンダウンし、タイマーは効果がありません。アクセスのためにドライブがスピンバックされると、ドライブは回転したままになります。
camcontrol standby /dev/ada0 -t 1200
ataidle
と同じ動作。
FreeNAS UIのストレージ->ディスク-> Adv。 PowerManagerの設定は単にcamcontrol
を呼び出すだけで、同様にタイマーは効果がありません。スタンバイを許可する電力設定(127など)が選択されている場合、ドライブはほぼ即座にスピンダウンし(場合によっては8秒後)、アクセスがある場合は常にスピンダウンします。
通常の「しばらく使用しない場合はスタンバイ」動作を取得するにはどうすればよいですか?
FreeBSD 11.2-STABLE
を介してFreeNAS 11.2
を使用します。ドライブは、4x Samsung 2TB 2.5インチ.T2000LM003`
# smartctl -P show /dev/ada0
smartctl 6.6 2017-11-05 r4594 [FreeBSD 11.2-STABLE AMD64] (local build)
Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org
Drive found in smartmontools Database. Drive identity strings:
MODEL: ST2000LM003 HN-M201RAD
FIRMWARE: 2BC10007
match smartmontools Drive Database entry:
MODEL REGEXP: ST(1500|2000)LM0(03|04|06|07|10) HN-M[0-9]*RAD
FIRMWARE REGEXP: .*
MODEL FAMILY: Seagate Samsung SpinPoint M9T
ATTRIBUTE OPTIONS: None preset; no -v options are required.
私はこれを非常に手動で行うことになりました。ドライブアクティビティをチェックし、ドライブがない場合はドライブをスピンダウンするスクリプトを作成し、このスクリプトをcronジョブとしてスケジュールします。
私は、iostat
を使用してドライブを設定された期間(私の場合は600秒(10分))監視するアプローチを採用しました。 iostat
が使用状況を報告しない場合は、ataidle -s /dev/ada[0123]
を呼び出してドライブを一時停止します。このスクリプトを15分ごとに呼び出すようにcronジョブを設定しました:*/15 * * * * spindown_if_idle.sh 600
spindown_if_idle.sh
:
#!/bin/bash
# argument is the number of seconds to test for drive use, default to 5
if [ -z "$1" ]; then
SECONDS=5
else
SECONDS="$1"
fi
function list_ada_drives {
# emit a list of hard drives, i.e. ada0 ada1 ada2 ...
iostat -x | grep "ada" | awk '{print $1}'
}
function spindown {
# for every hard drive use ataidle to place it in standby
for ADA in $(list_ada_drives); do
ataidle -s /dev/$ADA
done
}
function are_drives_used {
# argument is number of seconds to test over
# run iostat for the specified number of seconds and ask to report any usage
# -z means to omit any drives that are idle
# iostat will print two reports, the first since boot and the second during the interval
# The first tail and grep strip off the first useless report. The second tail strips off the header
# The final grep strips off drives we're not interested in
iostat -x -z -d $SECONDS 2 | tail -n +2 | grep -A5000 "extended" | tail -n +3 | grep "ada" -q
}
if are_drives_used $SECONDS ; then
echo "Drives are being used"
else
echo "Drives are idle, going to standby"
spindown
fi
collectd
で記録された過去の使用状況をクエリすることで、この10分のブロックを回避しようとしました。 rrdtool fetch
を使用して/var/db/collectd/rrd/localhost/disk-ada0
に格納されているメトリックを照会しましたが、それらには数分の遅延があります。それらに依存するということは、スクリプトが最近アイドル状態だった場合にアクティブに使用されているドライブをスタンバイする可能性があることを意味します。
次のスクリプトは、各ドライブがアイドル状態か回転中かを報告します。テストに役立ちます。
is_spinning.sh
:
#!/bin/sh
camcontrol devlist | grep ada | awk -F\( '{print $2'} | awk -F",|\\\\)" '{print $2}' |while read LINE
do
CM=$(camcontrol cmd $LINE -a "E5 00 00 00 00 00 00 00 00 00 00 00" -r - | awk '{print $10}')
if [ "$CM" = "FF" ] ; then
echo "$LINE: SPINNING"
Elif [ "$CM" = "00" ] ; then
echo "$LINE: IDLE"
else
echo "$LINE: UNKNOWN"
fi
done
このフォーラム投稿 に基づいています。
このアイデアをありがとう。私はこの問題に数日間苦しんでいました。私はbashスクリプトの作成に慣れていないため、python3で書き直しました。多分誰かがそれが役に立つと思うでしょう:
import subprocess
import time
drives_to_check = ['ada3', 'ada4', 'ada5']
no_sleep_hours = ['00', '01']
seconds = 600
if time.strftime("%H") in no_sleep_hours:
exit()
o = subprocess.check_output(f'/usr/sbin/iostat -x -z -d {seconds} 2', Shell=True)
for drive in drives_to_check:
if drive not in o.decode().split('extended')[-1]:
p = subprocess.check_output(f'/sbin/camcontrol cmd {drive} -a "E5 00 00 00 00 00 00 00 00 00 00 00" -r -', Shell=True)
if p.decode()[27:29] != '00':
q = subprocess.check_output(f'/usr/local/sbin/ataidle -s /dev/{drive}', Shell=True)
私の小さなアドオンは次のとおりです。スクリプトを実行したくない場合は、no_sleep_hoursに時間を追加できます。また、チェックするドライブを「drives_to_check」に追加して、スピンダウンを実行しないドライブを除外できるようにする必要があります。おそらく、iostatとataidleのパスを調整する必要があります。これらは、FreeNASで使用されるパスです。パスは、which adaidle
またはwhich iostat
で見つけることができます。 */15 * * * * /usr/local/bin/python3 /path/to/the/folder/check_disk_usage_and_spindown.py
でcronに追加できます