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.

unRaid script to automatically spin up drives when network media player is used

Featured Replies

  • Author

OK... I changed the script slightly... basically just two lines need to be replaced in the original. 

 

Instead of relying on the exit status of the "grep" command I am using "cut" with a field delimiter of a space (-d " ") and grabbing the 4th field.  It is the number of pings received.  I can then compare that number with the expected number "1".

 

Ran it all night, with the extra logging enabled, no false detections of a media player online. 

 

These three lines:

            out=`ping -q -c 1 $i 2>/dev/null`

            echo "$out" | grep "received," 1>/dev/null 2>&1

            if [ "$?" = "0" ]

get replaced with these:

            out=`ping -q -c 1 $i 2>/dev/null`

            rec_count=`echo "$out" | grep "received" | cut -d " " -f4`

            if [ "$rec_count" = "1" ]

 

Give it a try and see if it works for you.

 

Joe L.

 

An updated copy of this script is now attached to the first post in this thread (now that attachments are working again)

It will be easiest to download, unzip, and install it from there.

The new script (without all the temporary debugging lines) will then look like this:

#!/bin/bash

######################################################################

#

# Spin up the unRaid disks when a media player is detected on line.

# (it is on line if it responds to a "ping" command over the network)

#

# Joe L.

# January 5, 2008

######################################################################

 

# List the media player IP addresses here.

# separate the IP addresses by spaces if there are more then one

mp_ip="192.168.2.21 192.168.2.22"

last_look_online="no"

 

# Determine if the unRaid array is on-line or not.  If not currently

# started, we do not want to be spinning up any drives.

get_status() {

    cmd status | strings >/tmp/$$spin_up_status

    STATUS=`grep mdState /tmp/$$spin_up_status | cut -d "=" -f2`

    PHYSICAL_DISKS=`grep "^rdevName.*=" /tmp/$$spin_up_status |

        cut -d "=" -f2`

}

 

# function to issue commands to the unRaid "md" device.

# specifically, we will use it to get the status of the array

cmd() {

    echo $* >/proc/mdcmd

    cat /proc/mdcmd

}

 

spin_up_drives() {

    # loop through the drives spinning them up

    # by reading a single "random" block from each disk

    # in turn.  We use "dd" commands in the background so

    # all the disks will be spun up in parallel

    # since the physical disks are listed three times, three random blocks are read from each drive. This should be enough

    # to ensure at least one of the blocks was not in the disk cache memory.

    for i in $PHYSICAL_DISKS $PHYSICAL_DISKS $PHYSICAL_DISKS

    do

        # determine the number of blocks on the drive

        blocks=`df -k /dev/$i | grep -v Filesystem|

        sed "s/\([^ ]*\) *\([^ ]*\) .*/\2/"`

 

        # calculate a (random) block number to be read somewhere

        # between block 1 and the max blocks on the drive

        skip_b=$(( 1+(`dd if=/dev/urandom count=1 2>/dev/null |

        cksum | cut -f1 -d" "`)%($blocks) ))

 

        # read the random block from the disk.  We use a random

        # block to try to ensure it is not in the cache memory

        # if the block was in the cache memory, the disk would

        # not spin up.

        dd if=/dev/$i of=/dev/null \

        count=1 bs=1k skip=$skip_b >/dev/null 2>&1 &

#echo "`date` ****** reading block $skip_b from $i " >>/var/log/spin_up.log

    done

}

 

check_mp_status() {

        mp_online="no"  # initialize to "no" until we learn otherwise

        # ping each of the media servers to determine if online

        for i in $mp_ip

        do

            # ping the media server, if it answers, it is online

            # echo "$out" | grep "received," 1>/dev/null 2>&1

            out=`ping -q -c 1 $i 2>/dev/null`

            rec_count=`echo "$out" | grep "received" | cut -d " " -f4`

            if [ "$rec_count" = "1" ]

            then

                mp_online="yes"

                # if one is online, we do not need to ping

                # any others, break out of the "for" loop.

                break;

            fi

        done

echo $mp_online

}

 

sleep_checking_status() {

    seconds_to_sleep=$1

    test_interval=10

    while  ( test $seconds_to_sleep -gt 0 )

    do

      get_status

      if [ "$STATUS" != "STARTED" ]

      then

          break

      fi

      sleep $test_interval

      seconds_to_sleep=$(( $seconds_to_sleep - $test_interval ))

    done

}

 

# create a lockfile so we do not start two of these spin_up processes

lockfile="/var/lock/spin_up_drives"

 

if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;

then

  trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT

 

  echo "`date` ****** spin_drives.sh started" >/var/log/spin_up.log

 

  # loop forever

  while true

  do

    get_status

    if [ "$STATUS" != "STARTED" ]

    then

        # if the array is not started, sleep a few seconds and loop to

        # check status once more

        sleep 2

    else

        # The array is started, see if any of the media players are

        # on-line. If they are, spin up the drives if we need to.

 

        online="no"  # initialize to "no" until we learn otherwise

        online=`check_mp_status`

 

        # if any media players are online, spin up the drives

        # and then sleep checking for status changes and we'll

        # see if they are still online next time through the loop.

 

        if [ $last_look_online = "no" ]

        then

            if [ $online = "yes" ]

            then

              last_look_online="yes"

              echo "`date` media player is online..." >>/var/log/spin_up.log

            fi

      else # last_look_online = yes

            if [ $online = "no" ]

            then

              last_look_online="no"

              echo "`date` media player offline..." >>/var/log/spin_up.log

            fi

      fi

      if [ $online = "yes" ]

      then

          spin_up_drives

          # we just spun up the drives, we don't need to do much

          # for the next 600 seconds unless the

          # array status changes, so sleep looking for changes

          sleep_checking_status 600

      else

          sleep 5

      fi

 

    fi

  done

 

    rm -f "$lockfile"

    trap - INT TERM EXIT

else

    echo "Failed to acquire lockfile: $lockfile."

    echo "Held by $(cat $lockfile)"

fi

 

Thanks Joe,

 

Trying the new version right now... Will report back! :)

 

Mark.

80 minutes later and all drives are still up :(  I'll leave it a while longer.

 

I currently have no password set on root BTW.  I hadn't realised this.  The reason I mention it is that the lack of spin down is not password access related.

 

Thanks,

 

Mark.

Seems to be working just fine Joe! :)

 

Not sure how long it took, but it's been a couple of hours since I last switched the media player on and all drives have happily spun down!

 

Great stuff!

 

Thanks again,

 

Mark.

 

[EDIT] Another startup of the MediaPlayer and all HDDs up again, another hour or so of no use and all have successfully spun down again! :D

Me too... works a charm... Thanks :)

  • 2 months later...

Very nice script.  Thanks!

 

  • 11 months later...

I love this script.  It makes having a media server work with unRAID so much more enjoyable.  It works great with XBMC on the orginial XBOX (kind of, see below).

 

However, after leaving it running for a while something goes wrong.  When I look at the top command I see that spin_drives.sh is maxing out one of my CPUs at 100%. 

 

top - 20:36:37 up 8 days,  2:44,  2 users,  load average: 1.03, 1.09, 1.05
Tasks:  92 total,   2 running,  89 sleeping,   0 stopped,   1 zombie
Cpu(s): 50.0%us,  0.0%sy,  0.0%ni, 50.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4151240k total,  4097816k used,    53424k free,   208140k buffers
Swap:  4249152k total,      156k used,  4248996k free,  3353284k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
21129 root      20   0  4140 2288  312 R  100  0.1   4102:31 spin_drives.sh

 

When I look at the running processes I can actually see two instances of spin_drives.sh.  Is that correct?

 

root     29570     1  0  1035  2888   0 Mar12 ?        00:00:17 /bin/bash /boot/spin_drives.sh
root     21129 29570 99  1035  2288   0 Mar13 ?        2-20:19:07  \_ /bin/bash /boot/spin_drives.sh

I don't see anything in my syslog pertaining to this but could easily post one if someone thought it would help out.  Does anybody else have this problem or have a suggestion as how to fix it?

 

Thanks very much.

  • 2 years later...

I just found this post, and couldn't find anything newer discussing it, so I'm resurrecting it :)

 

If I understand correctly, this script will ping any of the IP addresses I fill in, and if any of them respond, it will spin up the drives, as long as the array is running.  A very clever idea actually, thanks for sharing!

 

Now, the reason I'm bringing out of the "old, forgotten posts" bin, is to ask if

 

A) is there any reason this won't work with 5b13?  Or, any changes that I need to make to it now?

 

B) how might one amend the script so that if/when NONE of the IP addresses respond, it spins them down?  I have it set to spin down after 45 minutes, but if I shut off the receiver, and HTPC and my Desktop, no one will need the drives spinning, so I might as well force them to spin down now, and not wait another 45 mintues, no?  I can set agressive sleep policies on the other machines, to shut them down quickly, so why not propigate that onto the server?

 

C) will this script still work if I force unRAID into sleep mode?  Or will I need to have all machines send a magic packet upon startup in that case?

 

Thanks again for being so generous with your clever talents, they have been very useful to me the last month or so, since I discovered unRAID  :D

 

 

I'm trying to use this on 5b12, and it doesn't spin up the disks. It notices a player is online and does the 3 random reads from each drive, but the main tab of the admin app shows all the drives with blinking green icons.

... but the main tab of the admin app shows all the drives with blinking green icons.

 

Did you refresh the page?

yes, i did. thanks for checking

  • 3 months later...

yes i recently tried this too. 5b11

 

I have my spin down set for 15 minutes and it spun the drives up when i turned on the media player but after 15 minutes the drives still spun down as normal with the player on

  • 1 year later...

Hi,

Is this script working under the latest RC?

Thanks

Perhaps it will need new logic to make the drive seem busy.

This is definitely a nice concept -- hopefully Joe will update it so it works with v5.

 

It seems that one thing you'd want to do is reserve IPs in your router so the media player(s) always get the same IP  [or just use static IPs ... which may not be a good choice if you have portable units that are sometimes connected elsewhere].

 

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.