Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

How can I monitor drive spindowns

Featured Replies

Hi,

 

I am trying to figure out a way to monitor my hard-drive spin-downs/-ups for a longer period of time, say a week or two. At the moment I have the feeling that my drives are almost always all active causing pretty high power consumption, but it is only a feeling, I would like some real data for this and the log output is kind of hard to follow (lots of spindown messages in there, but I can't really tell for how long and when they woke up without guessing. Is there a way to monitor the spindown state without waking the drives up ? A very simple bash script that monitors the relevant disk state and logs the status every 15 minutes to a file would be perfectly sufficient, I don't know if that is possible though without waking up the drives ?

 

Thanks!

You can monitor last IO time by checking the output of

/root/mdcmd status

 

I use the following to determine the last_io time of my disks.  you can adapt to log every 15 minutes or so if you like.

#!/bin/bash
#Assume inactive if no read/write in 900 seconds if $1 arg is not given.

if [ "$1" = "-q" ]
then
  quiet_mode=yes
  shift
else
  quiet_mode=no
fi

if [ "$1" = "-a" ]
then
   verbose_mode=yes
   shift
else
   verbose_mode=no
fi

no_activity_time=${1-900}

#Get the disk spinup status
disk_status=`/root/mdcmd status | strings | grep rdevLastIO`
# Get the current time.
now=`date +%s`
longest_elapsed_time=0
most_recent_disk_activity=100000000
most_recent_disk=""

function hms() {
    seconds=$1
    hours=$(($seconds / 3600))
    seconds=$(($seconds - ($hours * 3600)))
    minutes=$(($seconds / 60))
    seconds=$(($seconds - ($minutes * 60)))
    [ "$hours" = "0" ] && hours="" || hours="$hours hours, "
    [ "$minutes" = "0" ] && minutes="" || minutes="$minutes minutes, "
    echo $hours$minutes$seconds
}

for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
do
    last_access=`echo "$disk_status" | grep "rdevLastIO.$i=" | cut -d"=" -f2`
    if [ "$last_access" = "" ]
    then
      continue
    fi

    elapsed_time=$(expr $now - $last_access)
    i=`printf "disk%d" $i`

    [ $verbose_mode = yes ] && echo "Most recent disk I/O was on $i `hms $elapsed_time` seconds ago."
    if [ "$last_access" != "0" ]
    then
       if [ ${elapsed_time} -le ${most_recent_disk_activity} ]
       then
          most_recent_disk_activity=${elapsed_time}
          most_recent_disk="$i"
       fi
       if [ ${elapsed_time} -gt ${longest_elapsed_time} ]
       then
          longest_elapsed_time=${elapsed_time}
       fi
    fi
done

if [ $longest_elapsed_time = 0 ]
then
    [ $quiet_mode = no ] && echo "No disks are spinning."
    exit 0
else
    if [ $most_recent_disk_activity -gt $no_activity_time ]
    then
        [ $quiet_mode = no ] && echo -n "All disks inactive for at least `hms $no_activity_time` seconds. "
        [ $quiet_mode = no ] && echo "Most recent disk I/O was on $most_recent_disk `hms $most_recent_disk_activity` seconds ago."
        exit 0
    else
        [ $quiet_mode = no ] && echo "Most recent disk I/O was on $most_recent_disk `hms $most_recent_disk_activity` seconds ago."
        exit 1
    fi
fi

 

invoked as

last_io.sh

it will print the most recent IO time.

invoked as

last_io.sh -a

it will tell you if which, if any disk has been active within the past 900 seconds. (15 minutes)

the exit status will be 0 if all idle within 900 seconds, even if still spinning. 

The exit status will be 1 if any activity within 900 seconds.

 

You can change the time test by adding an argument to the command

last_io.sh 600

will check if there was activity within 600 seconds.

 

You can show all the disks individually with

last_io.sh -a

or

last_io.sh -a 600

 

you can make it completely silent by using the -q option

last_io.sh -q

or this time checking for activity within 1800 seconds.

last_io.sh -q 1800

 

When I experimented with a cache drive I used this to invoke the mover script only when the disks have not been written/read  from the past 15 minutes.

 

In my cron entry for the mover script I used a simplified version named "are_disks_idle.sh"

The cron entry looked like this:

*/5 * * * * /boot/are_disks_idle.sh && /usr/local/sbin/mover 2>&1 | logger

#!/bin/bash
###############################################
# are_disks_idle.sh
# exit status = 0 if all disks idle
# exit status = 1 if any disk spinning
# exit status = 2 if array is not atarted
#
# April 2010 Joe L.

# Check if the array is started
if [ -d /mnt/cache0 ]
then
  # rdevLastIO will be non-zero if a disk is spinning
  last=`/root/mdcmd status | grep -a rdevLastIO | grep -v '=0'`
  if [ "$last}" = "" ]
  then
    # all disks are idle
    exit 0
  else
    # all disks are not idle
    exit 1
  fi
else
  # array is not started
  exit 2
fi

 

 

have fun.  Since unRAID is tracking the last IO to a given disk, you do not need to spin them up to see if they have been active lately.

 

  • Author

Interesting, thanks alot !

 

This will probably replace the method I found while googling for some time this afternoon, but for the sake of providing an alternative solution I will post what I have found:

 

This comes from this blog post here: http://blog.th-neumeier.de/2011/03/suspend-idle-harddisks-and-monitor-the-suspension/

 

The script on that webpage uses "smartctl -a -n standby /dev/sdX" to query the state of the harddisk without spinning up the drives. It then allows writing the result of that query to a sqlite database and generates a report from that on demand.

 

The cronjob entry looks like this:

*/1 * * * * /boot/extra/disk-suspend-state.sh1 collect 1>/dev/null 2>&1

 

And a

/boot/extra/disk-suspend-state.sh1 generate

 

Gives me a detailes report of what has happened in the last day.

Here is an example output, that also details why I will probably switch to your solution:

 

sdg:

4541 - min Start Stop Count

4542 - max Start Stop Count

1 - difference

States:

97 - active/idle

216 - standby

sdh:

- min Start Stop Count

- max Start Stop Count

- - difference

States:

314 - standby

sdi:

1490 - min Start Stop Count

1490 - max Start Stop Count

0 - difference

States:

60 - active/idle

254 - standby

 

As you can see, three different drives (they are different drive types) report different SMART values, making things a bit hairy.

 

The start-stop-count values seem very unreliable, either they aren't reported at all or they don't change even if there is a change. What worked is the report for the drive states. The drives are monitored every minute, and as you can see that drive /dev/sdi for example was on for around 60 minutes (exactly what I have set for the idle time until drive powerdown) and then in standby for the rest of the time. For /dev/sdg this differed, which is reasonable since there was activity on my server that mgiht have caused a read from the drive.

 

Thank you very much for posting your script though: it works without a sqlite database and it should give me all the info I need, so this will probably replace what I have!

 

Archived

This topic is now archived and is closed to further replies.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.