sheevaplugに付けた外付けHDDを勝手に止めるようにする。
http://www.nslu2-linux.org/wiki/FAQ/SpinDownUSBHarddisks#method3
ほとんどここにあったスクリプトのパクリ
ポイントはいくつかあるが、、、
まずはsdparmを使う点。
syncだったところをsdparm –command=sync
scsi-idleをsdparm –command=stop にする。
(–command=syncしたあとじゃないと、stopしても止まらないので注意。)
次に、ディスクのデバイスファイルは、さしなおしたりしたときに毎回同じにふられるとは限らないので、とりあえずマウントポイントから、起動時にmountコマンドをつかってデバイスファイルに関連付け。(/dev/disk/by-uuidからls -lでリンク先を見ればデバイスファイル名を取れるが、ディスク入れ替え時にいちいち対応しないといけないので、、、ちょっと迷ったがこっちの方式で利用。)
最後に、一つのスクリプトで複数のディスクを(何個でも)扱えるようにした点。
ま、見ての通り。
スクリプトはこんな感じ
—
#!/bin/sh
mount=(/mnt/disk /mnt/backup)
num=${#mount[@]}
interval=4000
for ((i=0; i < num;i++)); do
tmp=(`mount |grep ${mount[i]}`)
[ x"$tmp" = x ] && continue
tmp1=${tmp[0]#/dev/}
disk[i]=${tmp1%[0-9]}
state[i]=`grep " ${disk[i]} " /proc/diskstats`
up[i]=1
count[i]=$interval
done
while [ true ]; do
sleep 600
for ((i=0;i < num;i++)); do
count[i]=$((${count[i]}-600))
newstate[i]=`grep " ${disk[i]} " /proc/diskstats`
[ `echo ${newstate[i]} | wc -l` -eq 1 ] || continue
if [ "${state[i]}" = "${newstate[i]}" ]; then
if [ ${count[i]} -lt 0 ]; then
count[i]=$interval
if [ ${up[i]} -eq 1 ]; then
echo -e "spin-down: /dev/${disk[i]}"
sdparm --command=sync /dev/${disk[i]}
state[i]=`grep " ${disk[i]} " /proc/diskstats`
sdparm --command=stop /dev/${disk[i]}
up[i]=0
fi
fi
else
echo -e "drive is up: /dev/${disk[i]}"
count[i]=$interval
state[i]="${newstate[i]}"
up[i]=1
fi
done # for i
done # for while loop
—
で、このスクリプトを適当に保存して、rc.localからバックグラウンドで起動する。
(最初は多重起動対策とか考えないといけないのかな?とか思っていたが、rc.localは、起動時に/var/lock以下にロックファイルを作成するため、ランレベル変更時など、さらに起動されることはないようだ(/etc/rc参照)
起動時にはK*を殺してからS*を起動するというのは知っていたが、この仕組みは知らなかったので、ちょっと迷った。2重起動対策はしなくてOK)
—
その後、sdparmにsda1など、パーティション番号の数字?を入れると/var/log/messagesに sending ioctl 2285 to a partition! というのがたくさん出てくるので、最後の数字をとるように変えました。