camcontrol device spindown/spinup scripts for zpools

Discussion in 'FreeBSD and FreeNAS' started by kfoda, Jan 6, 2011.

  1. kfoda

    kfoda New Member

    Joined:
    Jan 5, 2011
    Messages:
    11
    Likes Received:
    0
    Modify as you see fit, may be of interest for people looking to save power by spinning down the drives for a zpool when not is use. Also see http://forums.servethehome.com/showthread.php?36-FreeBSD-vault thread :

    ===================
    #!/usr/local/bin/bash

    #
    # zpool-spindown.sh
    # spindown ada/da camcontrol disks for a zpool
    # usage: zpool-spindown.sh poolname

    ZPOOL="$1"

    if [ -z "$ZPOOL" ]
    then
    echo "zpool name required"
    exit 2
    fi

    PATH=/usr/local/bin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/bin:/sbin
    export PATH

    # Cleanup any tmp file if present
    if [ -f /tmp/zpool.iostat ]
    then
    rm -f /tmp/zpool.iostat
    fi

    # Name of samba share to check if mounted
    SMBSHARE="media"

    # Get drives for pool
    drives=`zpool status $ZPOOL | egrep "da[0123456789]" | awk '{print $1}' | tr '\n' ' '`
    firstdrive=`echo "$drives" | awk '{print $1}'`

    # Activity checks
    smbactive=`smbstatus -S | grep -A 6 "Connected at" | grep $SMBSHARE | wc -l | awk '{print $NF}'`
    scrubrunning=`zpool status $ZPOOL | egrep "scrub in progress|resilver in progress" | wc -l | awk '{print $NF}'`
    spundown=`smartctl -n standby -H /dev/$firstdrive | tail -1 | grep "STANDBY" | wc -l | awk '{print $NF}'`

    # modify /etc/periodic/weekly/310.locate to touch /tmp/locate.running and remove when finished
    #
    if [ -f /tmp/locate.running ]
    then
    echo "Locate running...Aborting spindown!"
    exit 3
    elif [ $smbactive -gt 0 ]
    then
    echo "Samba share is mounted...Aborting spindown"
    exit 3
    elif [ $scrubrunning -eq 1 ]
    then
    echo "Scrub/resilver is running...Aborting spindown"
    exit 3
    elif [ $spundown -eq 1 ]
    then
    echo "Spundown already...Aborting spindown"
    exit 3
    fi

    # Longer IO Activity check - only perform if got past above
    zpool iostat $ZPOOL 30 2 | tail -1 > /tmp/zpool.iostat
    reading=`cat /tmp/zpool.iostat | awk '{print $(NF-1)}' | awk -F\. '{print $1}' | sed -e 's/K//g' | sed -e 's/M//g'`
    writing=`cat /tmp/zpool.iostat | awk '{print $NF}' | awk -F\. '{print $1}' | sed -e 's/K//g' | sed -e 's/M//g'`
    rm -f /tmp/zpool.iostat

    if [ $reading -gt 0 ]
    then
    echo "Pool shows IO activity...Aborting spindown"
    exit 3
    elif [ $writing -gt 0 ]
    then
    echo "Pool shows IO activity...Aborting spindown"
    exit 3
    fi

    drives=($drives)
    type=""

    driveop () {
    drive=$1
    # Need to issue differnt command to ada vs da devices!!!
    type=`echo $drive | cut -c 1`
    if [ $type = "d" ]
    then
    camcontrol stop $drive
    elif [ $type = "a" ]
    then
    camcontrol standby $drive
    fi
    return
    }

    drives_count=${#drives[@]}
    index=0

    while [ "$index" -lt "$drives_count" ]
    do
    driveop ${drives[$index]}
    printf "Spindown Drive %s\n" ${drives[$index]}
    let "index = $index + 1"
    done
    =================

    =================
    #!/usr/local/bin/bash

    #
    # zpool-spinup.sh
    # spinup ada/da camcontrol disks for a zpool
    # usage: zpool-spinup.sh poolname

    ZPOOL="$1"

    if [ -z "$ZPOOL" ]
    then
    echo "zpool name required"
    exit 2
    fi

    PATH=/usr/local/bin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/bin:/sbin
    export PATH

    # Get drives for pool
    drives=`zpool status $ZPOOL | egrep "da[0123456789]" | awk '{print $1}' | tr '\n' ' '`
    firstdrive=`echo "$drives" | awk '{print $1}'`

    # Check if already spun down
    spundown=`smartctl -n standby -H /dev/$firstdrive | tail -1 | grep "STANDBY" | wc -l | awk '{print $NF}'`

    if [ $spundown -eq 0 ]
    then
    echo "Pool $ZPOOL aready spun up"
    exit 3
    fi

    drives=($drives)

    type=""

    driveop () {
    drive=$1
    type=`echo $drive | cut -c 1`
    if [ $type = "d" ]
    then
    camcontrol start $drive
    elif [ $type = "a" ]
    then
    camcontrol idle $drive
    fi
    return
    }

    drives_count=${#drives[@]}
    index=0

    while [ "$index" -lt "$drives_count" ]
    do
    driveop ${drives[$index]}
    printf "SpinUp Drive %s\n" ${drives[$index]}
    let "index = $index + 1"
    done
    ================
     
    #1
  2. Yann

    Yann New Member

    Joined:
    Apr 25, 2015
    Messages:
    1
    Likes Received:
    0
    Hello kfoda, signed up to say thank you. I am running this script with very few patches, it does exactly what I needed, and you saved me several hours of work. Thanks a lot!
     
    #2
Similar Threads: camcontrol device
Forum Title Date
FreeBSD and FreeNAS FreeNAS SLOG Device? Aug 12, 2017
FreeBSD and FreeNAS Inexpensive SSD for SLOG Device? Mar 22, 2017

Share This Page