http://martin.hinner.info/mybook/spindown.php from Martin Hinner.
This method is originally explained in
http://gentoo-wiki.com/HOWTO_HDD_spindown_small_server and
http://kyyhkynen.net/stuff/mybook/.
I have just modified the needed scripts to work on MBWE.
Make sure you are in superuser mode
# su
Update hdparm. The default busybox version of hdparm is broken,
it reports the state of the disks always as "active/idle", even if the disk is in standby mode.
Make a directory for source files
# mkdir /tmp/src/ # cd /tmp/src/
Download and install hdparm
# wget http://download.sourceforge.net/sourceforge/hdparm/hdparm-7.7.tar.gz # tar -zxvf hdparm-7.7.tar.gz # cd hdparm-7.7 # ./configure # make # make install # cd .. # rm -rf hdparm-7.7*
Do not play with hdparm unless you really know what you are doing, you might end up with a damaged hard drive.
Get the smart_spindown script, place it to /usr/sbin and its access rights
# wget http://kyyhkynen.net/stuff/mybook/smart_spindown # mv smart_spindown /usr/sbin # chmod 0700 /usr/sbin/smart_spindown # chown root:root /usr/sbin/smart_spindown
Then you should tinker with the settings in the beginning of the
smart_spindown (see comments in the script for details). At this time
just set the name(s) of your disk(s).
You might want to first test drive the script with the logging output
echoed to stdout. So don't touch the lines involving logging just
yet.
Also, leave the WAITTIME (= the amount of time in seconds of disk
inactivity to wait before spinning the disks down) to a fairly small amount so
you don't have to wait too long. 60 or 120 will do just fine, just set it to a
longer period after you have tested that the script works. I have mine set to 300 (= 5 minutes).
#!/bin/bash
#
# smart_spindown
#
# Copyright (C) 2003 by Bart Samwel
#
# You may do with this file (and parts thereof) whatever you want, as long
# as my copyright notice is retained.
#
# Extended by joerk at gentoo-wiki.com
# Modified to fit WD MyBook World external hard drives by kyyhkynen at gmail.com
#
###################################################################
#
# Configuration
#
# Disk(s) to monitor.
# If you have only one disk, leave DISK2=sdb empty
DISK1=sda
DISK2=
# The base "no reads" wait time (in seconds). This is multiplied by
# the backoff factor to determine the real "no reads" wait time.
WAITTIME=300
# The maximum "no reads" wait time (in seconds).
# This also limits the backoff factor: the backoff factor cannot increase
# above a value that makes the "no reads" wait time larger than MAXWAIT.
# Default is 1200 seconds.
MAXWAIT=1200
# Time (in seconds) between polls to see if the disk is active again.
# Default is 30 seconds.
POLLTIME=30
# Output levels. Level 2 is verbose, level 1 is normal output.
# Enable all levels you would like to see.
OUTLEVEL1=true
OUTLEVEL2=true
# Decide which output to use. Useful if run in daemon mode
# echo or logger
# output1 is logged to normal, output2 to debug syslog
# Is PID of this shell logged?
OUTPUT1=echo
OUTPUT2=echo
#OUTPUTTAG="$(basename -- $0)[$$]"
#OUTPUT1="logger -t $OUTPUTTAG -p user.notice --"
#OUTPUT2="logger -t $OUTPUTTAG -p user.debug --"
#
# End of configuration. You shouldn't have to change lines below this :)
#
#########################################################################
# Device name(s) for the disk(s).
DEVNAME1=/dev/$DISK1
[ "$DISK2" ] && DEVNAME2=/dev/$DISK2
[ -z "$DISK2" ] && DEVNAME2=
# Stats file: the file used to monitor the disk's read activity.
# The first entry in this stats file must represent the read activity.
STATSFILE1=/sys/block/$DISK1/stat
STATSFILE2=/sys/block/$DISK2/stat
# Multiplication factor for the backoff after a spinup, in percentages.
# Default is 300 = factor 3.
BACKOFF_INCREASE_PCT=400
# Multiplication factor for the backoff at every poll that shows that
# the disk is spun down. This determines how fast the backoff value
# decreases.
BACKOFF_DECREASE_PCT=98
# Enable this if you don't use laptop_mode. This will make the script
# sync before spinning down the disc. To make this work, you must
# ensure that:
# 1. /proc/sys/vm/dirty_expire_centisecs is set to a high value. You can
# use 60000 for 10 minutes.
# 2. /proc/sys/vm/dirty_writeback_centisecs is set to the same value.
# 3. Your ext3 filesystems are mounted with "commit=n", where n is the
# number of seconds between commit. Use 600 for 10 minutes.
NO_LAPTOP_MODE=true
#
# Let's go!
#
# Number of poll times that the disc was found to be spun down.
POLLSSPUNDOWN=0
# Number of spindowns performed
SPINDOWNS=0
# Number of times (*100) the WAITTIME of no-reads required before spindown
BACKOFF_FACTOR=100
# Stats: Total time the disk has been up.
UPTIME=0
# Total duration of last spun-down period.
LASTDOWNTIME=-1
# Total duration of the last spun-up period.
LASTUPTIME=0
# Duration of the last poll. Always equal to POLLTIME except the first
# time around.
LASTPOLLTIME=0
# Make sure the stuff we use is in the cache. I've seen it happen
# that the script spun the disk down, and then "sleep" wasn't in
# the cache and the disk spun right up again. :)
true
false
sleep 1
# Log the end of script execution
trap "$OUTPUT1 'Exiting.'" EXIT
if [ "$DISK2" ] ; then
$OUTLEVEL1 && ${OUTPUT1} "Monitoring spindown opportunities for disks $DISK1 and $DISK2." ;
else
$OUTLEVEL1 && ${OUTPUT1} "Monituring spindown opportunities for disk $DISK1." ;
fi ;
if ($OUTLEVEL1) ; then
hdparm -C $DEVNAME1 $DEVNAME2 |grep active >/dev/null
if [ "$?" == "0" ] ; then
[ "$DISK2" ] && ${OUTPUT1} "A drive is currently spun up." ;
[ -z "$DISK2" ] && ${OUTPUT1} "The drive is currently spun up." ;
else
[ "$DISK2" ] && ${OUTPUT1} "Both drives are currently spun down." ;
[ -z "$DISK2" ] && ${OUTPUT1} "The drive is currently spun down." ;
fi ;
fi
while [[ /sbin/true ]]; do
hdparm -C $DEVNAME1 $DEVNAME2 |grep active >/dev/null
if [ "$?" == "0" ] ; then
THISWAIT=$(($WAITTIME*$BACKOFF_FACTOR/100)) ;
if [[ $THISWAIT -gt $MAXWAIT ]] ; then
THISWAIT=$MAXWAIT ;
fi ;
# Increase the backoff irrespective of whether we failed
# or not. The backoff should drop again by the lack of
# spinups afterwards.
BACKOFF_FACTOR=$(($BACKOFF_FACTOR*$BACKOFF_INCREASE_PCT/100)) ;
if [[ $(($BACKOFF_FACTOR*$WAITTIME/100)) -gt $MAXWAIT ]] ; then
BACKOFF_FACTOR=$(($MAXWAIT*100/$WAITTIME)) ;
fi ;
UPTIME=$(($UPTIME+$LASTPOLLTIME)) ;
LASTUPTIME=$(($LASTUPTIME+$LASTPOLLTIME)) ;
if [ "$LASTDOWNTIME" -ge "0" ] ; then
$OUTLEVEL1 && ${OUTPUT1} "A drive spun up after $LASTDOWNTIME seconds. Total time up/down: $UPTIME/$(($POLLSSPUNDOWN*$POLLTIME)) (avg sleep time $(($POLLSSPUNDOWN*$POLLTIME/$SPINDOWNS)))" ;
fi
PREVIOUS_READS_DISK1=-1 ;
PREVIOUS_READS_DISK2=-1 ;
NEXT_READS_DISK1=-1 ;
NEXT_READS_DISK2=-1 ;
NUM_EQUALS=0 ;
$OUTLEVEL2 && ${OUTPUT2} "Waiting for $THISWAIT seconds of read inactivity..." ;
PREVIOUS_READS_DISK1=`cat $STATSFILE1 |awk '{ print $1; }'` ;
[ "$DISK2" ] && PREVIOUS_READS_DISK2=`cat $STATSFILE2 |awk '{ print $1; }'` ;
while [[ $(($NUM_EQUALS*5)) -lt $THISWAIT ]]; do
sleep 5 ;
UPTIME=$(($UPTIME+5)) ;
LASTUPTIME=$(($LASTUPTIME+5)) ;
NEXT_READS_DISK1=`cat $STATSFILE1 |awk '{ print $1; }'` ;
[ "$DISK2" ] && NEXT_READS_DISK2=`cat $STATSFILE2 |awk '{ print $1; }'` ;
if [[ $PREVIOUS_READS_DISK1 -ne $NEXT_READS_DISK1 ]] ; then
NUM_EQUALS=0 ;
PREVIOUS_READS_DISK1=$NEXT_READS_DISK1 ;
$OUTLEVEL2 && ${OUTPUT2} "$DISK1 read, restarting..." ;
else
if [ "$DISK2" -a $PREVIOUS_READS_DISK2 -ne $NEXT_READS_DISK2 ] ; then
NUM_EQUALS=0 ;
PREVIOUS_READS_DISK2=$NEXT_READS_DISK2 ;
$OUTLEVEL2 && ${OUTPUT2} "$DISK2 read, restarting..." ;
else
NUM_EQUALS=$(($NUM_EQUALS+1)) ;
$OUTLEVEL2 && ${OUTPUT2} "Seconds of quiet: $(($NUM_EQUALS*5))" ;
fi
fi
done
# We've just had $THISWAIT seconds of read inactivity. Writes can be
# cached, reads always spin up the disk; the inactivity indicates
# that we're ready to go to sleep. Laptop mode will have synced all
# writes for us after the last read, so we don't have to explicitly
# sync.
if ( $NO_LAPTOP_MODE ) ; then
sync ;
fi ;
hdparm -q -y $DEVNAME1 $DEVNAME2 ;
SPINDOWNS=$(($SPINDOWNS+1)) ;
$OUTLEVEL1 && ${OUTPUT1} "Drive(s) spun down after $LASTUPTIME seconds (with $THISWAIT seconds of inactivity), total spin down count: ${SPINDOWNS}." ;
LASTUPTIME=0 ;
LASTDOWNTIME=0 ;
else
POLLSSPUNDOWN=$(($POLLSSPUNDOWN+1)) ;
if [[ $SPINDOWNS -eq 0 ]] ; then
SPINDOWNS=1 ;
fi
LASTDOWNTIME=$(($LASTDOWNTIME+$LASTPOLLTIME)) ;
BACKOFF_FACTOR=$(($BACKOFF_FACTOR*$BACKOFF_DECREASE_PCT/100)) ;
if [ $BACKOFF_FACTOR -lt 100 ] ; then
BACKOFF_FACTOR=100 ;
fi
fi ;
if ( $OUTLEVEL2 ) ; then
${OUTPUT2} "spindowns: $SPINDOWNS, time up/down: $UPTIME/$(($POLLSSPUNDOWN*$POLLTIME)), backoff $BACKOFF_FACTOR, down for $LASTDOWNTIME (avg $(($POLLSSPUNDOWN*$POLLTIME/$SPINDOWNS)))." ;
fi ;
sleep $POLLTIME ;
LASTPOLLTIME=$POLLTIME ;
done
Now let's test the script. First, set the kernel parameters so that the disk writes will be cached. Later on, the service startup script will take care of these, but now that we are only testing, we'll have to set them manually.
# echo 0 > /proc/sys/vm/dirty_expire_centisecs # echo 0 > /proc/sys/vm/dirty_writeback_centisecs # echo 95 > /proc/sys/vm/dirty_ratio # echo 10 > /proc/sys/vm/dirty_background_ratio # echo 5 > /proc/sys/vm/laptop_mode # echo 40 > /proc/sys/vm/swappiness
If you are interested in how each of the paremeters affect the system, here is a brief explanation.
Start the script, don't do anything else with the MBWE and watch the output. If you have the box nearby, you'll probably also hear the spin-downs and spin-ups.
# /usr/sbin/smart_spindown
Leave the script running for a couple of hours and you'll see if the disks spin up unintentionally. If they do, you'll probably have to reduce the disk usage somehow.
With my MBWE it seems to take some time after a reboot for the script to start really working. So wait patiently. Leave the script running for example for a night. Even if it keeps spinning up and down, one night doensn't probably kill your disks, right? :)
If the script works just fine, kill it by pressing CTRL+C.
Now tweak the settings in the beginning of the script. Set the
WAITTIME to serve your needs; I have mine set to 300 (= 5 minutes).
Then set the MAXWAIT (= the amount of time in seconds of disk
inactivity to wait at most, the time is changing dynamically between
WAITTIME and MAXWAIT) accordingly.
Also, mind the logging options. If you would like to log the output to
syslog, uncomment the lines with logger. To disable logging and
thus reduce disk activity, set both OUTLEVEL1 and OUTLEVEL2 to
false.
Next, we'll make the script start and stop automatically.
Download the script to start/stop the service, put it into
/etc/init.d/ and set its access rights. Then make a symbolic link to
stop the service when the MBWE is shutting down.
# wget http://kyyhkynen.net/stuff/mybook/S50smart_spindown # mv S50smart_spindown /etc/init.d # chmod 0700 /etc/init.d/S50smart_spindown # chown root:root /etc/init.d/S50smart_spindown # ln -s /etc/init.d/S50smart_spindown /etc/init.d/K50smart_spindown
The scripts in the directory/etc/init.d/starting withS[number]are automatically run during system startup with parameterstart. The number defines the order the scripts are run. Likewise, scripts starting withK[number]are run when the system is shutting down with parameterstop.
This step is optional. If the script seems to work ok for you, you don't
necessarily need to do this. You can try this also later if you find it
necessary. Edit your fstab with caution; you might mess your drives up
by playing around with it.
Find this line in /etc/fstab:
/dev/md3 /var ext3 defaults,noatime 0 2
Change it into this:
/dev/md3 /var ext3 defaults,noatime,commit=43200 0 2
Changing this line causes the filesystem on /var (where log files
and all frequently accessed stuff is located) to commit its journal to the
disk only twice a day, thus reducing disk access.
Reboot your MBWE.
# reboot
You will lose your SSH connection during the boot, so reconnect to the MBWE.
The script should be now running. You can check it like this:
# ps -A | grep smart
You're done here. Enjoy your new sleepy MBWE.
If you want to tweak your settings without rebooting the whole device, just make your changes to the script and restart it by
# /etc/init.d/S50smart_spindown restart
If your disk(s) keep spinning up randomly, see next section for further tips.
There are many running services in your MBWE that access the disks, thus making it spin up when it really shouldn't. I addition, they are using memory, which the MBWE doesn't have to spare. Here we'll turn some of them off.
Make sure you are in superuser mode
# su
Disable mionet. It uses lots of memory. If you really want to securely access your MBWE from anywhere, I strongly recommend using SSH/SFTP.
In order to prevent mionet from starting during boot, edit /etc/init.d/mionet.sh.
Comment out this line:
$MIONETD start
Then stop the service:
# /etc/init.d/mionet.sh stop
Disable the cron job that is writing the time to a file. I really haven't figured out where the file is even used.
Edit /etc/crontabs/root.
Comment out the only line that can be commented out (if you havent set any cron jobs of your own):
7 * * * * date +%m%d ...
Disable the service that displays the disk usage with the leds in the front panel of your MBWE. Admit it, the feature is pretty much useless and because the service has to check the amount of free space on the disk(s), it is causing disk access.
In order to prevent the service from starting during boot, edit /etc/init.d/S15wdc-fuel-gauge.
Comment out this line:
$FGD &
Then stop the service:
# /etc/init.d/S15wdc-fuel-gauge stop
Disable ntpd log. You really don't need to know that stuff.
Edit /etc/ntp.conf.
just point the logfile to /dev/null
logfile /dev/null
Restart ntpd to reload the configuration.
# /etc/init.d/ntp.sh restart
Of course, you could disable the whole ntpd and update the clock
only during boot or with a cron job. But it is up to you.
Disable the default temperature monitoring service. More on that in the next section.
Disable syslogd and klogd. If you don't know what they are
used for, you won't need them. And, you can always start them if you need to
debug something.
Of course, you could move the logs to your ramdisk (see next step), but the
busybox version of syslogd doesn't support a syslog.conf
configuration file that could be used to move the logfiles to another
location. So you would need to update syslogd to do that.
To prevent them from starting, edit /etc/inittab. Comment out these
lines:
::respawn:/sbin/syslogd -n -m 0 ::respawn:/sbin/klogd -n
Reboot.
Create a RAM disk and keep all the
frequently accessed log files, ntp.drift and samba's .tdb files there.
If you dont't know how a RAM disk works or what is is, I recommend reading the
wikipedia article before
proceeding.
Again, if you don't know your Linux, you might screw up your MBWE big time. so proceed with caution.
You're probably wondering, "weren't we supposed to free some memory instead of using it more?" Well that is up to you... my RAM disk eats one megabyte of memory, and it's half empty, so one could probably do with an even smaller ram disk.
The basic idea is to create a small RAM disk, configure the programs to use it and copy the data on it back to the disk when the disk is spinning.
In this example, we'll be moving just ntp.drift and samba's files to
the RAM disk. ntp.drift, because it is written frequently (if you have
ntpd running) and samba, because it spins my MBWE up every time I
start my Windows machine up and it mounts the samba share.
Of course, you could have disabled ntpd and might not have problem
with samba spinning the disks up, but you may set up other programs to use the
RAM disk, too. From this guide you'll get the basic idea how to do it,
though.
First, we'll create a RAM disk manually. Later on, you can do this with a startup script automatically, but let's just do it manually for practise :)
By default, the busybox linux used in the MBWE has five RAM disk devices, that are by default inactive and not in use. You can list them with
# ls -l /dev/ram*
Let's format a filesystem to ram1:
# /sbin/mke2fs -vm 0 /dev/ram1 1024
The number 1024 defines the size of the RAM disk in kilobytes. One megabyte should be more than enough.
Next, we'll have to mount the disk. We will mount the ramdisk to
/mnt/ramdisk/. You may use another path, but then you'll have to
remember to configure the programs accordingly.
# mkdir /mnt/ramdisk # /bin/mount -t ext2 /dev/ram1 /mnt/ramdisk/
And behold, we have a working RAM disk.
Then, let's configure ntpd to keep the drift file on the RAM disk by
editing /etc/ntp.conf. The drift file contains the estimated clock
frequency error and it is updated whenever the ntpd checks the time
from the time server. Find the line beginning with driftfile and change
it to
driftfile /mnt/ramdisk/ntp.drift
Then copy the driftfile to the RAM disk and restart ntpd:
# cp /etc/ntp.drift /mnt/ramdisk # /etc/init.d/ntp.sh restart
Next, configure samba to use the ramdisk. Edit /var/oxsemi/smb.conf
and change the following lines:
smb passwd file=/mnt/ramdisk/private/smbpasswd private dir=/mnt/ramdisk/private log file=/mnt/ramdisk/log.%m lock directory=/mnt/ramdisk/locks pid directory=/mnt/ramdisk/locks
Edit /etc/init.d/samba.sh and set the log directory to the RAM disk
by editing the line in the start function:
/usr/local/samba/sbin/nmbd -D -s/var/oxsemi/smb.conf -l/mnt/ramdisk
Finally edit /etc/inetd.conf and change the log directory there, too
:
netbios-ssn stream tcp nowait root /usr/local/samba/sbin/smbd smbd -s/var/oxsemi/smb.conf -l/mnt/ramdisk -d0
Next, copy the files to the RAM disk:
# mkdir /mnt/ramdisk/locks # cp /var/locks/* /mnt/ramdisk/locks/ # mkdir /mnt/ramdisk/private # cp /var/private/* /mnt/ramdisk/private/ # cp /var/log/log.* /mnt/ramdisk/
Then, restart samba:
# /etc/init.d/samba.sh restart
If everything went well, and you got no errors, samba and ntpd are
now using the RAM disk.
Now, this process should be made to happen automatically during boot. You can either roll your own startup script or just use mine:
# wget http://kyyhkynen.net/stuff/mybook/S13ramdisk # mv S13ramdisk /etc/init.d # chmod 0700 /etc/init.d/S13ramdisk # chown root:root /etc/init.d/S13ramdisk # ln -s /etc/init.d/S13ramdisk /etc/init.d/K71ramdisk
The script looks like this:
#!/bin/sh
#
case "$1" in
start)
/sbin/mke2fs -vm 0 /dev/ram1 1024
/bin/mount -t ext2 /dev/ram1 /mnt/ramdisk/
cp /etc/ntp.drift /mnt/ramdisk/
cp /var/log/log.* /mnt/ramdisk/
mkdir /mnt/ramdisk/locks
cp /var/locks/* /mnt/ramdisk/locks/
mkdir /mnt/ramdisk/private
cp /var/private/* /mnt/ramdisk/private/
;;
backup)
cp /mnt/ramdisk/ntp.drift /etc/
cp /mnt/ramdisk/locks/* /var/locks/
cp /mnt/ramdisk/log.* /var/log/
cp /mnt/ramdisk/private/* /var/private/
;;
stop)
$0 backup
;;
restart|reload)
$0 backup
;;
*)
echo $"Usage: $0 {start|stop|restart|backup}"
exit 1
esac
exit $?
As you an see, with parameter start, the RAM disk is created and the
needed files are copied to it. With parameter backup the files are
copied back to the disk.
Note: the order the RAM disk script is run during the startup is important; the RAM disk must be created before any services using it are started.
Because all the data on the RAM disk is lost in case of a power failure,
you probably should copy the files on the RAM disk back to the disk more often
than just during a shut down. I have done this by adding a line to the
smart_spindown script to the point where the disk spin up is detected.
This way, the RAM disk is copied back to the disk every time the disk has spun
up, thus keeping the files pretty much up to date.
In order to do this, find the following line in the smart_spindown
script:
THISWAIT=$(($WAITTIME*$BACKOFF_FACTOR/100)) ;
It should be line number 142, if you haven't added any lines to the beignning of the script. Before that line, add a line containing:
/etc/init.d/S13ramdisk backup
And restart the smart_spindown script:
# /etc/init.d/S50smart_spindown restart
And behold, your RAM disk is backed up to the disk every time the disk(s) start spinning.
Copy the whole system to an USB stick and run it from there. Frequently written files could be kept on a ram disk (see previous step) to maximize the USB stick's lifetime.
I haven't really tried this, it's just an idea. This would really minimize disk access, if it was possible. And why wouldn't it be, this is linux we're talking about here :)
Any ideas concerning this would be appereciated...
The needed steps would be:
1. Clone system files to an USB stick. My current system files take about 350 megabytes of space, so a 512 MB stick should be enough.
2. During boot, check if there is an USB drive plugged in and if it contains the system files. Could also perform some checks to ensure the stick is healthy.
3. chroot to the stick and continue running the system from
there.
Ok, so your MBWE keeps spinning up and down and you want to find out what's causing it? Here's how to do it.
Make sure you are in superuser mode
# su
First, you have to stop syslogd and klogd if you haven't
already done that. We will be logging disk access and we don't want it to be
logged on a log file, thus causing disk activity, which causes more log
entries, which causes more disk access... and so on. You got the point. If you
didn't, don't mess with your MBWE.
To prevent them from starting, edit /etc/inittab. Comment out these
lines:
::respawn:/sbin/syslogd -n -m 0 ::respawn:/sbin/klogd -n
Reboot.
Enable I/O debugging
# echo 1 > /proc/sys/vm/block_dump
Now, all that's happening in your disks will be logged to your kernel ring buffer. You'll see its contents with
# dmesg
The output will have lots of stuff from your last boot in the beginning, so you might want to clear the buffer with
# dmesg -c
Now, leave your MBWE alone for a while.
After a while, your ring buffer will be full of lines like
<7>dmesg(10078): READ block 2525104 on md1
Typically, one line describes one block access. First, there is the name of
the executable, then its process id and finally the description of what
happened. So this line means that dmesg was reading the disk (md1).
When a process is writing to the disk, the line will look like:
<7>tail(10976): dirtied inode 45 (temperature.log) on ram1
This means that tail was writing to the file temperature.log
on my ram disk. Actually, the data has been written to the write buffer in
memory and will be written to the disk after a while. The actual write will be
indicated by a line like this:
<7>pdflush(36): WRITE block 984 on ram1
So, after your MBWE spins up
unintentionally, check with dmesg what was causing it.
Remember to turn off I/O debugging off afterwards with
# echo 0 > /proc/sys/vm/block_dump
With the default temperature monitoring service on the MBWE, you can't set the limits for when the fan should be spinning how fast. With my simple replacement shell script you can.
Note: if you own the MBWE I i.e. the single disk version, this script is pretty much useless, since the single disk version doesn't have a fan.
A text editor and the know-how to use it. I recommend installing
nano, but vi will also do just fine.
An up-to-date version of hdparm. See the first section
for installation instructions.
Make sure you are in superuser mode
# su
Disable the original temperature monitoring service. Edit the file
/etc/init.d/S15wdc-heat-monitor. Comment out this line:
$HEAT_MON &
Then stop the service
# /etc/init.d/S15wdc-heat-monitor stop
Download my shell script and the script used to start it as a service, move them to right places and set treir access rights:
# wget http://kyyhkynen.net/stuff/mybook/temperature_monitor # mv temperature_monitor /usr/sbin # chmod 0700 /usr/sbin/temperature_monitor # chown root:root /usr/sbin/temperature_monitor # wget http://kyyhkynen.net/stuff/mybook/S51temperature_monitor # mv S51temperature_monitor /etc/init.d # chmod 0700 /etc/init.d/S51temperature_monitor # chown root:root /etc/init.d/S51temperature_monitor # ln -s /etc/init.d/S51temperature_monitor /etc/init.d/K51temperature_monitor
The scripts in the directory
/etc/init.d/starting withS[number]are automatically run during system startup with parameterstart. The number defines the order the scripts are run. Likewise, scripts starting withK[number]are run when the system is shutting down with parameterstop.
Edit the settings in the beginning of the script (see comments in the script for details).
#!/bin/sh
# An alternative temperature monitoring and fan control script for
# WD MyBook World Edition external hard drives
#
# Copyright (C) 2007 by kyyhkynen at gmail.com
#
# You may do with this file (and parts thereof) whatever you want, as long
# as my copyright notice is retained.
#
#######################################################################
#
# Configuration settings
#
# Disk(s) to monitor.
# If you have only one disk, leave DISK2 empty
# In that case, however, this script is pretty much useless.
DISK1=sda
DISK2=sdb
# Temperature limits for speeds.
# When the temperature of the disk(s) drop below TEMP_LIMIT_0, the fan speed is set to 0
# When the temperature of the disk(s) is between the limits, the fan speed is set to 50
# When the temperature of the disk(s) is above TEMP_LIMIT_50, the fan speed is set to 100
TEMP_LIMIT_0=43
TEMP_LIMIT_50=55
# The amount of time (in minutes) to wait before turning the fan off after the disk(s) have been spun down.
SPINDOWN_WAIT=10
# Logging stuff
LOG_ENABLED=false
LOG_INTERVAL=5
LOGGER=echo
#
# End of configuration. You shouldn't need to touch lines below this :)
#
#######################################################################
# Device name(s) for the disk(s).
DEVNAME1=/dev/${DISK1}
DEVNAME2=/dev/${DISK2}
# The file controlling the fan speed
FAN_SPEED=/sys/devices/platform/wdc-fan/speed
# Get current fan speed
CURRENT_FAN_SPEED=`cat ${FAN_SPEED}` ;
LOG_COUNTER=0
SPINDOWN_COUNTER=0
while [[ /bin/true ]]; do
TEMPERATURE_DISK1=$(smartctl -d ata -A ${DEVNAME1}|grep Tempera|cut -c 88-90) ;
hdparm -C $DEVNAME1 |grep active >/dev/null
if [ "$?" == "0" ] ; then
STATUS_DISK1=u ;
else
STATUS_DISK1=d ;
fi ;
if [ -z "$DISK2" ] ; then
TEMPERATURE_DISK2=$TEMPERATURE_DISK1 ;
STATUS_DISK2=$STATUS_DISK1 ;
else
TEMPERATURE_DISK2=$(smartctl -d ata -A ${DEVNAME2}|grep Tempera|cut -c 88-90) ;
hdparm -C $DEVNAME2 |grep active >/dev/null
if [ "$?" == "0" ] ; then
STATUS_DISK2=u ;
else
STATUS_DISK2=d ;
fi ;
fi ;
if [ $STATUS_DISK1 = "d" -a $STATUS_DISK2 = "d" ] ; then
if [ $CURRENT_FAN_SPEED -gt 0 ] ; then
SPINDOWN_COUNTER=$((SPINDOWN_COUNTER+1)) ;
if [[ $SPINDOWN_COUNTER -ge $SPINDOWN_WAIT ]] ; then
echo 0 > $FAN_SPEED ;
CURRENT_FAN_SPEED=0 ;
SPINDOWN_COUNTER=0 ;
fi ;
fi ;
else
if [ $TEMPERATURE_DISK1 -ge $TEMP_LIMIT_0 -o $TEMPERATURE_DISK2 -ge $TEMP_LIMIT_0 ] ; then
if [ $TEMPERATURE_DISK1 -ge $TEMP_LIMIT_50 -o $TEMPERATURE_DISK2 -ge $TEMP_LIMIT_50 ] ; then
echo 100 > $FAN_SPEED ;
CURRENT_FAN_SPEED=100 ;
else
if [ $CURRENT_FAN_SPEED -lt 50 ] ; then
echo 100 > $FAN_SPEED ;
sleep 2 ;
fi ;
echo 50 > $FAN_SPEED ;
CURRENT_FAN_SPEED=50 ;
fi ;
else
echo 0 > $FAN_SPEED ;
CURRENT_FAN_SPEED=0 ;
fi ;
fi ;
LOG_COUNTER=$((LOG_COUNTER+1));
if [[ $LOG_COUNTER -ge $LOG_INTERVAL ]] ; then
$LOG_ENABLED && ${LOGGER} "${TEMPERATURE_DISK1}${STATUS_DISK1} ${TEMPERATURE_DISK2}${STATUS_DISK2} ${CURRENT_FAN_SPEED}" ;
LOG_COUNTER=0 ;
fi ;
sleep 60 ;
done
Start the service.
# /etc/init.d/S51temperature_monitor start
You're done.
If you want to tweak your settings, just edit the script and restart the service afterwards with
# /etc/init.d/S51temperature_monitor restart
Hint: if you turn on the logging, you can build nice graphs of your drive temperature with the data (see example).