Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env bash
- # sas-spindown.sh by David Froehlich <dfroe@gmx.de>
- #
- # Uses iostat to spindown sas devices which cannot be
- # controlled by 'camcontrol idle'.
- #
- # List of all monitored devices.
- DEVICES=""
- # The following command retrieves this list by calling camcontrol
- # and filtering all devices connected to the first scsi bus
- # (i.e. the lsi sas controller without any onboard sata devices).
- DEVICES="$DEVICES
- `camcontrol devlist | grep 'scbus[0] target [1-9][0-9]*' \
- | grep -o 'da[0-9][0-9]*'`"
- # Uncomment to also add all ahci devices.
- #DEVICES="$DEVICES
- #`camcontrol devlist | grep -o 'ada[0-9][0-9]*'`"
- # Timeout in minutes.
- # A spindown command will be sent to all monitored devices
- # which had no activity during the last n minutes.
- TIMEOUT=30
- # Path to some binary which should normally be within $PATH.
- IOSTAT="`which iostat`"
- CAMCONTROL="`which camcontrol`"
- #
- # Do not edit any lines below unless you know what you are doing!
- #
- # Check for valid device list.
- if [ -z "$DEVICES" ] ; then
- echo "Error: Device list is empty!" >&2
- exit 1
- fi
- # Check for valid device list.
- if ! printf "%d" "$TIMEOUT" >/dev/null 2>&1 ; then
- echo "Error: Timeout \"$TIMEOUT\" is not a number!" >&2
- exit 1
- fi
- # Check for required binaries.
- for i in IOSTAT CAMCONTROL ; do
- eval bin=\$$i
- if ! [ -x "$bin" ] ; then
- echo "Error: $i binary \"$bin\" is not executable!" >&2
- exit 1
- fi
- done
- # Create and initialize internal variables $INACTIVITY_<device>
- # containing the number of minutes a device has been inactive.
- for dev in $DEVICES ; do
- eval INACTIVITY_$dev=0
- done
- # Increment the configured timeout by one.
- # This is a fix because the check whether a device has reached
- # the threshold is performed at the beginning of each iostat run
- # before the statistics are parsed (and not after).
- TIMEOUT=$(($TIMEOUT+1))
- # Try to determine the first column of the first and second line
- # of the iostat headlines.
- # These will be used to separate multiple iostat runs.
- IOSTAT_COLUMNS="`$IOSTAT -d -I -x | head -n 2 | \
- while read first_column remaining_columns
- do
- echo $first_column
- done`"
- for col in $IOSTAT_COLUMNS ; do
- if [ -z "$IOSTAT_1stLINE_1stCOLUMN" ] ; then
- IOSTAT_1stLINE_1stCOLUMN="$col"
- elif [ -z "$IOSTAT_2ndLINE_1stCOLUMN" ] ; then
- IOSTAT_2ndLINE_1stCOLUMN="$col"
- fi
- done
- # Jump into an infinite loop by calling iostat to print
- # statistics every 60 seconds to stdout. Note that only
- # devices with activity will be included.
- # The first column of the output will be stored as $device
- # and everything else as $usage.
- $IOSTAT -d -I -x -z -t da -w 60 |
- while read device usage
- do
- # Skip empty lines.
- if [ -z "$device" ] ; then
- continue
- fi
- # First line of a new iostat run.
- if [ "$device" = "$IOSTAT_1stLINE_1stCOLUMN" ] ; then
- # Increment the inactivity counter of all devices.
- for dev in $DEVICES
- do
- eval old_counter=\$INACTIVITY_$dev
- new_counter=$(($old_counter+1))
- eval INACTIVITY_$dev=\$new_counter
- done
- continue
- fi
- # Second line of a new iostat run.
- if [ "$device" = "$IOSTAT_2ndLINE_1stCOLUMN" ] ; then
- # Check whether the inactivity counter of a device
- # has reached the configured threshold.
- for dev in $DEVICES
- do
- eval counter=\$INACTIVITY_$dev
- if [ $counter -eq $TIMEOUT ] ; then
- # Sending spindown command to $dev
- $CAMCONTROL stop $dev >/dev/null
- fi
- done
- continue
- fi
- # If $device is a device with activity
- # (which is true when the script comes to this position
- # because iostat is called to only print active devices)
- # then reset its inactivity counter.
- eval INACTIVITY_$device=0
- done
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement