wheezy向けの旧ページはこちら

8.USBHDDの定期的なスピンダウン方法 - RaspberryPiで各種サーバー作り! - ある阪大生の物置小屋

ファイル共有用途等でUSBHDDの電源を長期的に入れておく場合、静かな所だと動作音が気になったりします。
ここでは、「hdparm」や「sdparm」を用いて、定期的にUSBHDDをスピンダウンし、動作音を抑える方法について説明します。

8.1.「hdparm」・「sdparm」のインストール

USBHDDによって、「hdparm」・「sdparm」のどちらが動作するかはわからないようです。
チェックのため両方インストールして動作する方を利用しましょう。
「hdparm」と「sdparm」をインストールするには、以下のコマンドでインストールできます。

sudo apt-get install hdparm sdparm

8.2.「hdparm」・「sdparm」の動作チェック

以下のコマンドで「hdparm」・「sdparm」のどちらが正しく動作するのか確認します。

#hdparmによるHDDスピンダウン
sudo hdparm -y /dev/(デバイス名)

#sdparmによるHDDスピンダウン
sdparm -r --command=stop /dev/(デバイス名)

(動作しなかった方はremoveしてもらってもOK)

8.3.「hdparm」・「sdparm」の常駐化

  1. 以下のような内容のスクリプトを「hdd_spindown.sh」として「/root」に「root権限」で保存します。
    #!/bin/sh
     
    if [ $# -lt 2 ]; then
            echo "not enough arguments supplied."
            echo "hdd_spindown.sh [UUID] [INTERVAL]"
            exit 0
    fi
     
    disk=`findfs UUID="$1"`
    interval=$2
     
    count=$interval
    up=1
     
    if [ -z $disk ]; then
            #echo "findfs error"
            exit 1
    fi
     
    disk=`echo "$disk" |sed -e "s@/dev/@@"`
     
    state=`grep " $disk " /proc/diskstats`
     
    while [ true ]; do
            sleep 10
            count=$(($count-10))
            newstate=`grep " $disk " /proc/diskstats`
            if [ "$state" = "$newstate" ]; then
                    if [ $count -lt 0 ]; then
                            count=$interval
                            if [ $up = 1 ]; then
                                    #echo -e "spin-down"
                                    sync
                                    state=`grep " $disk " /proc/diskstats`
    
    #hdparmを利用するとき
                                    hdparm -y /dev/$disk > /dev/null 2>&1
    #sdparmを利用するとき
                                    sdparm --command=stop -r /dev/$disk > /dev/null 2>&1
    
                                    up=0
                            fi
                    fi
            else
                    #echo -e "drive is up"
                    count=$interval
                    state="$newstate"
                    up=1
            fi
    done
    
    このスクリプトは、NSLU2-Linux - FAQ / SpinDownUSBHarddisksから引っ張ってきて、findfsを利用してUUIDを引数にできるようにいじったり、出力を吐かないようにしてます。
  2. 「/root/hdd_spindown.sh」のパーミッションを変更する。
    sudo chmod 700 /root/hdd_spindown.sh
    
  3. systemdの設定を変更して、スクリプトが起動時に実行されるようにする。
    まず、以下のコマンドで、対象のデバイスがどのUnit名でマウントされているか確認する。
    systemctl list-units| grep -F .mount
    
    次に、「/lib/systemd/system/user_hdd_spindown.service」を以下の内容で「root権限」で作成します。
    [Unit]
    Description=hdd spindown by sdparm
    After=(先ほど、確認したUnit名)
    
    [Service]
    ExecStart=/root/hdd_spindown.sh (USBHDDのUUID) (直近のアクセスからスピンダウンまでの時間(秒)) > /dev/null 2>&1
    KillMode=process
    Type=simple
    Restart=no
    
    [Install]
    WantedBy=multi-user.target
    
    最後に、以下のコマンドでスクリプトが起動時に動作するように設定する。
    sudo systemctl enable user_hdd_spindown.service
    
    (jessieからはシステム管理機能としてinitに変わりsystemdが採用されているので、/etc/inittabでは設定できなくなりました。)
  4. 動作確認
    再起動して正しくスピンダウンされるか確認する。

8.参考サイト

以下のページを参考にさせていただきました。

製品紹介(Amazonアフィリエイト)



2016/07/17 環境を変えた際にuser_hdd_spindown.serviceが起動時にfailedになることがあったので、[Unit]のAfterの記述を変更。