Freebsd

如何在計時器上使硬碟待機(降速)?

  • April 4, 2021

我想讓我的硬碟在空閒時減速,比如說 20 分鐘。任何分鐘數都可以,因為這個 NAS 很少使用。

我嘗試過但沒有奏效的方法:

  • ataidle -S 20 /dev/ada0只需立即停止驅動器,計時器就不起作用。一旦驅動器由於訪問而重新旋轉,它們就會保持旋轉。
  • camcontrol standby /dev/ada0 -t 1200相同的行為ataidle
  • FreeNAS UI 的儲存 -> 磁碟 -> 高級。電源管理器設置只是呼叫camcontrol,同樣計時器沒有效果。如果選擇了允許待機的電源設置(例如 127),則驅動器幾乎立即降速(可能在 8 秒後),並且如果有任何訪問,則不斷地升速和降速。更新:請參閱 如何讓 FreeNAS 降低磁碟轉速? 有關如何進行這項工作的說明並跳過手動腳本。

如何獲得正常的預期“如果一段時間不使用則待命”行為?

使用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.

更新:請參閱 https://serverfault.com/a/965694/184095 了解如何使 GUI 工作並跳過下面的手動腳本編寫過程。


我最終非常手動地完成了這項工作。編寫一個腳本來檢查驅動器活動,如果沒有驅動器則關閉驅動器,然後將此腳本安排為 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

收集的指標

我嘗試通過查詢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

基於此論壇文章

感謝這個想法。幾天來,我一直在為這個問題苦苦掙扎。由於我不習慣編寫 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 adaidlewhich iostat. 您可以將其添加到 cron */15 * * * * /usr/local/bin/python3 /path/to/the/folder/check_disk_usage_and_spindown.py

引用自:https://serverfault.com/questions/968303