Я бы хотел, чтобы мои жесткие диски останавливались во время простоя, скажем, 20 минут. Подойдет любое количество минут, так как этот NAS используется редко.
Что я пробовал и не сработало:
ataidle -S 20 /dev/ada0
просто немедленно останавливает привод, и таймер не действует. После того, как диски снова раскручиваются из-за доступа, они продолжают вращаться.
camcontrol standby /dev/ada0 -t 1200
такое же поведение как ataidle
.
Хранилище пользовательского интерфейса FreeNAS -> Диски -> Расшир. Настройка Power Manager просто вызывает 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.
Спасибо за идею. Я боролся с этой проблемой несколько дней. Поскольку я не привык писать сценарии 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, если не хотите, чтобы скрипт запускался. И вы должны добавить диски, которые вы хотите проверить, в «Drive_to_check», чтобы вы могли исключить диски, которые не должны выполнять остановку вращения. Возможно, вам придется настроить пути для iostat и ataidle, это пути, используемые во FreeNAS. Вы можете найти свой путь с помощью: which adaidle
или which iostat
. Вы можете добавить его в cron с помощью */15 * * * * /usr/local/bin/python3 /path/to/the/folder/check_disk_usage_and_spindown.py
В итоге я сделал это вручную. Напишите сценарий, который проверяет активность диска, останавливает диски, если их нет, а затем запланируйте этот сценарий как задание cron.
Я остановился на подходе, который использует iostat
для мониторинга дисков в течение заданного периода времени, в моем случае 600 секунд (10 минут). Если iostat
сообщает об отсутствии использования, звоните ataidle -s /dev/ada[0123]
чтобы приостановить диски. Я настраиваю задание cron для вызова этого скрипта каждые 15 минут: */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
Я попытался избежать этого 10-минутного блока, запросив историческое использование, записанное collectd
. я использовал 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
На основе это сообщение на форуме.