HOWTO_HDD_spindown_small_server
Contents |
Why?
- Why do you want to spin down your hard disk? Servers are not supposed to have disks spun down.
For most servers like file-, mail- or newsserver this is correct. Spinning up the disks would put unneccesary latency to the requests. Other services may very well have disks spun down like network gateways , firewalls or telephone servers. They don't have to store information for a longer time, so there is no need to store it on disks.
- Why don't you use flash disks or USB sticks?
I would, if they could stand some million write cycles. But todays (Aug '06) flash memory won't exceed more than 100.000 write accesses, which wears them down quite early. Just think of the server log written every 10 minutes. And each e2fs block makes one write access.
- Why don't you use noflushd? It works very well with my setup.
It did to mine back then, too. Until I switched from ext2 fs to ext3 fs. The journal data is written without use of the pdflush daemon, making noflushd obsolete.
- Why don't you use the laptop_mode script. It's maintainted and proven to work in the field.
I did, and it didn't match my demands. For example, the spin down time of the hard disk was limited to 10 minutes. Spinning up/down a normal desktop hard disk every 10 minutes wears it down within 6-8 months.
How ?
The goal is to spin down the disk for some hours until the cache misses on some read access or the writeback buffer is full. Then the disk is spun up and the read or write request is fulfilled. After that all pending write requests are written to disk by use of the laptop_mode setting >0. Some seconds later a last "sync" is called and the disk gets another spin down command.
Install
Requirements
- The predeccesor to the laptop_mode script smart_spindown from Bart Samwels page
- Your favorite ascii editor
- root access to the server
- logger from sys-apps/util-linux if you want to syslog the script output
Installation
smart_spindown
smart_spindown is located at Bart Samwels page You can download it here
Copy the script to your favorite place for system scripts, e.g. /usr/sbin/ and set the appropriate access rights e.g.
-rwx------ root root /usr/sbin/smart_spindown
(chmod 0700 /usr/sbin/smart_spindown; chown root:root /usr/sbin/smart_spindown).
To extend with logging functionality use this:
The script below is extended with calls to the "logger" command, which logs all messages to syslog (i.e. /var/log/messages). This setting seemed more suitable for a server process.
| File: /usr/sbin/smart_spindown |
#! /bin/bash
#
# smart_spindown rev. 1
#
# 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 www.gentoo-wiki.info
#
#
# How it works: This program monitors the read activity on a disk. If there
# is no read activity for a while, the disk is spun down. The time without
# read activity that is required is dynamic, using a backoff factor. When
# the recent spun-down periods are relatively short, this means that the
# machine might be busy with something, so the script tries to wait for
# longer periods without activity before spinning down again. When spun-down
# periods are long, the backoff factor is decreased, and the disk is spun
# down after shorter periods without read activity.
#
# This script REQUIRES that laptop_mode is enabled on your kernel. This is
# because it assumes that after a couple of seconds without read activity,
# all dirty blocks will be flushed. If this is not done, the disc will
# spin up at random times
#
# Configuration
#
# Output levels. Level 2 is verbose, level 1 is normal output.
# Enable all levels you would like to see.
OUTLEVEL1=true
OUTLEVEL2=false
# 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 --"
# Disk to monitor.
DISK=hda
# Device name for the disk.
DEVNAME=/dev/$DISK
# Stats file: the file used to monitor the disk's read activity.
# The first entry in this stats file must represent the read activity.
STATSFILE=/sys/block/$DISK/stat
# Multiplication factor for the backoff after a spinup, in percentages.
# Default is 300 = factor 3.
BACKOFF_INCREASE_PCT=300
# 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=96
# The base "no reads" wait time (in seconds). This is multiplied by
# the backoff factor to determine the real "no reads" wait time.
WAITTIME=20
# 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 120 seconds.
MAXWAIT=120
# Time (in seconds) between polls to see if the disk is active again.
# Default is 10 seconds.
POLLTIME=10
# 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 #false
#
# 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=0
# 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
$OUTLEVEL1 && ${OUTPUT1} "Monitoring spindown opportunities for disk $DISK."
if ($OUTLEVEL1) ; then
hdparm -C $DEVNAME |grep active >/dev/null
if [ "$?" == "0" ] ; then
${OUTPUT1} "Drive is currently spun up." ;
else
${OUTPUT1} "Drive is currently spun down." ;
fi ;
fi
while [[ /sbin/true ]]; do
hdparm -C $DEVNAME |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" != "0" ] ; then
$OUTLEVEL1 && ${OUTPUT1} "Drive spun up after $LASTDOWNTIME seconds." ;
fi
PREVIOUS_READS=-1 ;
NUM_EQUALS=0 ;
$OUTLEVEL2 && ${OUTPUT2} "Waiting for $THISWAIT seconds of read inactivity..." ;
PREVIOUS_READS=`cat $STATSFILE |awk '{ print $1; }'` ;
while [[ $(($NUM_EQUALS*5)) -lt $THISWAIT ]]; do
sleep 5 ;
UPTIME=$(($UPTIME+5)) ;
LASTUPTIME=$(($LASTUPTIME+5)) ;
NEXT_READS=`cat $STATSFILE |awk '{ print $1; }'` ;
if [[ $PREVIOUS_READS -ne $NEXT_READS ]] ; then
NUM_EQUALS=0 ;
PREVIOUS_READS=$NEXT_READS
$OUTLEVEL2 && ${OUTPUT2} "Restarting..." ;
else
NUM_EQUALS=$(($NUM_EQUALS+1)) ;
$OUTLEVEL2 && ${OUTPUT2} "Seconds of quiet: $(($NUM_EQUALS*5))" ;
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 $DEVNAME ;
SPINDOWNS=$(($SPINDOWNS+1)) ;
$OUTLEVEL1 && ${OUTPUT1} "Drive spun down after $LASTUPTIME seconds \(with $THISWAIT seconds of inactivity\)." ;
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
|
service start + stop script
Reuse an init script from the hddtemp guide.
| File: /etc/init.d/smart_spindown |
#!/sbin/runscript
# Copyright 1999-2006 joerk at www.gentoo-wiki.info
# Distributed under the terms of the GNU General Public License v2
# currently depend on nothing
# (maybe logger later on)
depend() {
:
}
SMART_SPINDOWN_SCRIPT=/usr/sbin/smart_spindown
SMART_SPINDOWN_PID=/var/run/$(basename ${SMART_SPINDOWN_SCRIPT}).pid
checkconfig() {
if [ ! -r $SMART_SPINDOWN_SCRIPT ] ; then
eerror "Spindown script not found at $SMART_SPINDOWN_SCRIPT"
return 1
fi
for A in dirty_expire_centisecs dirty_writeback_centisecs dirty_ratio dirty_background_ratio laptop_mode swappiness ; do
if [ ! -w /proc/sys/vm/$A ] ; then
eerror "VM config /proc/sys/vm/$A not writable"
return 1
fi
done
}
start() {
checkconfig || return 1
ebegin "Starting ${SVCNAME}"
echo 0 > /proc/sys/vm/dirty_expire_centisecs
echo 0 > /proc/sys/vm/dirty_writeback_centisecs
#echo 4320000 > /proc/sys/vm/dirty_expire_centisecs
#echo 4320000 > /proc/sys/vm/dirty_writeback_centisecs
echo 95 > /proc/sys/vm/dirty_ratio
#echo 60 > /proc/sys/vm/dirty_background_ratio
echo 10 > /proc/sys/vm/dirty_background_ratio
echo 5 > /proc/sys/vm/laptop_mode
echo 10 > /proc/sys/vm/swappiness
start-stop-daemon --start --quiet --background \
--pidfile ${SMART_SPINDOWN_PID} --make-pidfile \
--exec ${SMART_SPINDOWN_SCRIPT}
eend $?
}
stop() {
ebegin "Stopping ${SVCNAME}"
# "echo" before start-stop-deamon,
# so we get the error code of s-s-d as exit code
echo 3000 > /proc/sys/vm/dirty_expire_centisecs
echo 500 > /proc/sys/vm/dirty_writeback_centisecs
echo 40 > /proc/sys/vm/dirty_ratio
echo 10 > /proc/sys/vm/dirty_background_ratio
echo 0 > /proc/sys/vm/laptop_mode
echo 60 > /proc/sys/vm/swappiness
start-stop-daemon --stop --quiet --pidfile ${SMART_SPINDOWN_PID}
eend $?
}
|
mount options
With the "commit=" option, one can configure the ext3 fs how long to wait before committing the journal to disk. The parameter is given in seconds
/dev/hda3 / ext3 noatime,commit=43200 0 1
This setting syncs the journal at least twice a day.
The "noatime" option keeps the kernel from logging every (read and write) access to the file. Which would have filled the write buffer with unneccessary write commands and spun up the disk earlier.
Tweak settings
Script parameters
These settings can be adjusted in the spindown script
- OUTLEVEL1, OUTLEVEL2
How much do you want to read about your spin down attempts?
OUTLEVEL1 gives informations about the seconds between the disk being spin up and spin down.
OUTLEVEL2 gives debugging info during the 2 events.
- DISK
The disk to monitor. Only one disk can be specified. To monitor more disks, start all scripts in parallel.
- NO_LAPTOP_MODE=true
Despite my kernel setting of /proc/sys/vm/laptop_mode = 5, I switched off the laptop setting in the script. Now the kernel flushes the disk 5 seconds after the disk has spun up. But the script does not rely on this behavior, and gives a last "sync" command before spinning down again.
Kernel parameters
These settings can be adjusted in the init script
- /proc/sys/vm/dirty_expire_centisecs
Centi seconds to wait before flushing the write pages to disk. A higher value will increase the possibility of losing information, in case of a system crash/power failure after the disk spin down. Set to 0 to disable the feature.
- /proc/sys/vm/dirty_writeback_centisecs
A higher value will increase the possibility of losing information, in case of a system crash/power failure after the disk spin down. Set to 0 to disable the feature.
- /proc/sys/vm/dirty_ratio
Percentage of write pages to keep in memory before flushing the queue. Percentage relative to whole memory. May be clipped to 95% or even lower to prevent OOM conditions.
- /proc/sys/vm/dirty_background_ratio
Depending on laptop_mode: Percentage of write pages to keep after flushing the write queue (?)
- /proc/sys/vm/laptop_mode
Set to a value > 0 enables laptop mode. The value describes the flush of the write queue after a disk spinup [in seconds]. Set this to 0 to disable laptop mode.
- /proc/sys/vm/swappiness sets the percentage of swapping out memory.
A high value favours swapping to disk, a low value favours keeping in memory. Setting this to a low value keeps the kernel from using the swap partition.
Links
- http://www.xs4all.nl/~bsamwel/smart_spindown/index.html Bart Samwels page about smart_spindown
- http://www.samwel.tk/laptop_mode/ Bart Samwels page about laptop mode
- https://wiki.ubuntu.com/ReducedPowerUsage some reference to kernel parameters
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and list their apartments, townhouses and units.
