Advertisement
Guest User

sas-spindown.sh

a guest
Mar 4th, 2012
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.75 KB | None | 0 0
  1. #!/usr/bin/env bash
  2.  
  3. # sas-spindown.sh by David Froehlich <dfroe@gmx.de>
  4. #
  5. # Uses iostat to spindown sas devices which cannot be
  6. # controlled by 'camcontrol idle'.
  7. #
  8.  
  9.  
  10. # List of all monitored devices.
  11. DEVICES=""
  12.  
  13. # The following command retrieves this list by calling camcontrol
  14. # and filtering all devices connected to the first scsi bus
  15. # (i.e. the lsi sas controller without any onboard sata devices).
  16. DEVICES="$DEVICES
  17. `camcontrol devlist | grep 'scbus[0] target [1-9][0-9]*' \
  18.                    | grep -o 'da[0-9][0-9]*'`"
  19.  
  20. # Uncomment to also add all ahci devices.
  21. #DEVICES="$DEVICES
  22. #`camcontrol devlist | grep -o 'ada[0-9][0-9]*'`"
  23.  
  24.  
  25. # Timeout in minutes.
  26. # A spindown command will be sent to all monitored devices
  27. # which had no activity during the last n minutes.
  28. TIMEOUT=30
  29.  
  30.  
  31. # Path to some binary which should normally be within $PATH.
  32. IOSTAT="`which iostat`"
  33. CAMCONTROL="`which camcontrol`"
  34.  
  35.  
  36. #
  37. # Do not edit any lines below unless you know what you are doing!
  38. #
  39.  
  40.  
  41. # Check for valid device list.
  42. if [ -z "$DEVICES" ] ; then
  43.   echo "Error: Device list is empty!" >&2
  44.   exit 1
  45. fi
  46.  
  47. # Check for valid device list.
  48. if ! printf "%d" "$TIMEOUT" >/dev/null 2>&1 ; then
  49.   echo "Error: Timeout \"$TIMEOUT\" is not a number!" >&2
  50.   exit 1
  51. fi
  52.  
  53. # Check for required binaries.
  54. for i in IOSTAT CAMCONTROL ; do
  55.   eval bin=\$$i
  56.   if ! [ -x "$bin" ] ; then
  57.     echo "Error: $i binary \"$bin\" is not executable!" >&2
  58.     exit 1
  59.   fi
  60. done
  61.  
  62. # Create and initialize internal variables $INACTIVITY_<device>
  63. # containing the number of minutes a device has been inactive.
  64. for dev in $DEVICES ; do
  65.   eval INACTIVITY_$dev=0
  66. done
  67.  
  68. # Increment the configured timeout by one.
  69. # This is a fix because the check whether a device has reached
  70. # the threshold is performed at the beginning of each iostat run
  71. # before the statistics are parsed (and not after).
  72. TIMEOUT=$(($TIMEOUT+1))
  73.  
  74. # Try to determine the first column of the first and second line
  75. # of the iostat headlines.
  76. # These will be used to separate multiple iostat runs.
  77. IOSTAT_COLUMNS="`$IOSTAT -d -I -x | head -n 2 | \
  78. while read first_column remaining_columns
  79. do
  80. echo $first_column
  81. done`"
  82. for col in $IOSTAT_COLUMNS ; do
  83.   if [ -z "$IOSTAT_1stLINE_1stCOLUMN" ] ; then
  84.     IOSTAT_1stLINE_1stCOLUMN="$col"
  85.   elif [ -z "$IOSTAT_2ndLINE_1stCOLUMN" ] ; then
  86.     IOSTAT_2ndLINE_1stCOLUMN="$col"
  87.   fi
  88. done
  89.  
  90. # Jump into an infinite loop by calling iostat to print
  91. # statistics every 60 seconds to stdout. Note that only
  92. # devices with activity will be included.
  93. # The first column of the output will be stored as $device
  94. # and everything else as $usage.
  95. $IOSTAT -d -I -x -z -t da -w 60 |
  96. while read device usage
  97. do
  98.  
  99.   # Skip empty lines.
  100.   if [ -z "$device" ] ; then
  101.     continue
  102.   fi
  103.  
  104.   # First line of a new iostat run.
  105.   if [ "$device" = "$IOSTAT_1stLINE_1stCOLUMN" ] ; then
  106.     # Increment the inactivity counter of all devices.
  107.     for dev in $DEVICES
  108.     do
  109.       eval old_counter=\$INACTIVITY_$dev
  110.       new_counter=$(($old_counter+1))
  111.       eval INACTIVITY_$dev=\$new_counter
  112.     done
  113.     continue
  114.   fi
  115.  
  116.   # Second line of a new iostat run.
  117.   if [ "$device" = "$IOSTAT_2ndLINE_1stCOLUMN" ] ; then
  118.     # Check whether the inactivity counter of a device
  119.     # has reached the configured threshold.
  120.     for dev in $DEVICES
  121.     do
  122.       eval counter=\$INACTIVITY_$dev
  123.       if [ $counter -eq $TIMEOUT ] ; then
  124.         # Sending spindown command to $dev
  125.         $CAMCONTROL stop $dev >/dev/null
  126.       fi
  127.     done
  128.     continue
  129.   fi
  130.  
  131.   # If $device is a device with activity
  132.   # (which is true when the script comes to this position
  133.   # because iostat is called to only print active devices)
  134.   # then reset its inactivity counter.
  135.   eval INACTIVITY_$device=0
  136.  
  137. done
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement