OpenWrt Forum Archive

Topic: Putting a USB attached hard-drive into Standby

The content of this topic has been archived on 6 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Has anyone encountered a program that exists for Linux, Openwrt, or could be made into a package that issues an ATA Standby command to a USB attached hard-drive so it "spins-down" after some amount of idle time?

I have been looking for this as well.

On a Linux box with IDE interface, we can use hdparm to spin down the hard disk. Unfortunately I am using ASUS WL500GD which only has USB interface, so hdparm does not work.

Hi

Most (all) modern ATA drives have the facility to go into a standby state (usually ~1W compared to ~20W running).  They also have an internal timer that can send them into standby when a certain period of inactivity passes.  However, the timer typically defaults to 'off' and needs to be set up with an ATA command.  The hdparm utility on linux is useful for setting this if the device is connected via IDE.

Hard drives in external USB enclosures are controlled by a microcontroller in the hard drive enclosure, which translates between USB "Mass Storage Class" "Bulk Only Transport" commands and the ATA commands that most drives accept.

The specification for the USB "Bulk Only Transport" (see below) shows how USB packets are used to 'wrap' disk access commands.  These commands are an ill-defined subset of SCSI commands (nebulously called 'SCSI transparent').

Unfortunately, the specification is not hard and fast; the way in which this translation is implemented seems to vary between external USB enclosure (chipset) manufacturers.

There is no SCSI command to tell a drive to power itself off automatically after a time period so you simply cannot use the drive's internal standby timer (the enclosure offers no way of getting it to send the appropriate ATA command).

However, SCSI does specify a command to send the drive to sleep immediately, called START_STOP_UNIT.  Some enclosures will accept this SCSI command and generate the appropriate ATA command to send the drive to standby.  (I have two external enclosures, one does, one doesnt).

You can compile the utility "scsi-spin" which comes in the debian "scsitools" package for OpenWRT - scsi-spin will generate the correct SCSI commands to send a drive to sleep immediately (provided the enclosure supports this translation).

Furthermore, you can use a bit of code like this (below) to run in the background, check disk activity through /proc/diskstats and send the disk a START_STOP_UNIT command if no activity has been seen for some time:

#!/bin/sh

interval=$1
disk="sda"
opwnwrtdisk="/dev/discs/disc0/disc"

state=`grep " $disk " /proc/diskstats`
count=$interval
up=1

while [ true ]; do
   sleep 10
   count=$(($count-10))
   newstate=`grep " $disk " /proc/diskstats`
   if [ "$state" = "$newstate" ]; then
      if [ $count -lt 0 ]; then
         count=$interval
         if [ $up = 1 ]; then
            #echo -e "spin-down\t" `date`
            sync
            state=`grep " $disk " /proc/diskstats`
            scsi-spin -d -f $openwrtdisk
            up=0
         fi
      fi
   else
      #echo -e "drive is up\t" `date`
      count=$interval
      state="$newstate"
      up=1
   fi
done

Note: you will have to correct the device names sda and /dev/discs/disc0/disc for your system - these work for my Kamikaze installation r5530

If there is an apetite for it, I could make an ipkg for the scsi-spin utility and this script

Cheers

John


References:
USB Mass Stroage Class spec:
http://www.usb.org/developers/devclass_ … ulk_10.pdf
http://www.usb.org/developers/devclass_ … ew_1.2.pdf

SCSI commands:
http://en.wikipedia.org/wiki/SCSI_command

Very useful:
http://www.nslu2-linux.org/wiki/FAQ/Spi … BHarddisks (thanks for base script)
http://packages.debian.org/unstable/uti … tools.html

johncass wrote:

If there is an apetite for it, I could make an ipkg for the scsi-spin utility and this script

Developers are always hungry, patches are welcome !

--
Nico

I would appreciate scsi-spin package too! Pleeeease

Because of the problems mentioned here with USB enclosures, I took a rather obtuse approach. 

I bought  USB enclosures for a 2.5 inch drives (like in a laptop) for a couple of 60GB Hitachi drives from old IBM laptops.

Hitachi publishes a stand-alone utility on their web site that allows one to change all of the drive settings including the one that controls when the drive "sleeps". The actual terminology is a bit different than "sleep" but moving the slider to "power saving" accomplishes the intended function.

The trick is to remove the production drive from a laptop and install the drive you wish to change and boot the utility from the floppy.

Once you have changed the setting and put the drive in the enclosure, it powers itself down after the specified inactivity time.

Oh yeah, don't forget to put the production drive back in the laptop and remove the utility from the floppy.

Net result, I have 2-60 GB drives attached to my WRTSL54GS that power-down after my sepcified inactivity interval.

Regards,
Jim

johncass, it seems that you disappeared. We can wait for the package, but our hard-disk are exhausted due to the 24/7 service.

Dear All

SCSI-SPIN package.

Apologies for not posting this earlier, I have put the package source tar.gz and an IPKG up on:

http://www.johnkerry.plus.com/scsi-spin.html

This is kind of temporary, I will tidy up but I hope you'll be able to get your disks spinning down from here...

Kind Regards

John

Thank you for posting the package.

Unfortunately I have an Asus 500g Deluxe with OpenWrt 0.9 and gives segmentation fault the scsi-spin binary.

Hi zsjoska

sorry the binary package (IPKG) is not working directly, I built it for kamikaze openWRT linux 2.6 running on Netgear WGT634U (broadcom mipsel processor)

I think your machine has the same processor but maybe your configuration is different, causing the segmentation fault.

can you try building the source on your configuration to see if that works? 
 

John

I could not make a such promise to the community since I doesn't have the environment. I will try when I will have hard disk space :-D but hopely someone will be quicker.

Hello!

I've modified johncass' source package to compile for Whiterussian 0.9 and compiled it. You can download ipkg http://crym.ru/files/misc/openwrt/0.9/s … mipsel.ipk and sources http://crym.ru/files/misc/openwrt/0.9/s … n.patch.gz http://crym.ru/files/misc/openwrt/0.9/scsi-spin.tar.gz
Please, let me know if it works for you. For me it doesn't segfault, but gives an error like this:

# scsi-spin -d -f /dev/discs/disc0/disc
scsi-spin [warning]: device is mounted but --force is passed
SG_IO: status = 0x0 cmd = 0x1b
Invalid argument
start/stop failed

or simply doesn't spin down my disk if I run it like this:

# scsi-spin -d --oldioctl -f /dev/discs/disc0/disc
scsi-spin [warning]: device is mounted but --force is passed

Though, I guess it is due to my drive serving files when I try to stop it.

Thanks everyone!  Here are my results.

I get the same results as asaw with asaw's packages.  I'm not local to my asus wl500gp so I can't tell if the drive  has actually in sleep mode or not though.

I attempted to use johncass' script, but was hindered by the lack of /proc/diskstats on my whiterussian 0.9 image.

EDIT:  Checked the disc, and it doesn't spin down after the command is issued.

(Last edited by clearchris on 6 May 2007, 01:30)

Hi there....

On my Asus WL-500gP with WR 0,9 i have sucess with Oleg´s SCSI-STOP, and this script:

----
#!/bin/sh

if /usr/bin/[ $# -ne 1 ]; then
        /bin/echo 1>&2 "Usage: $0 <device>"
        exit 1
fi

PERIOD=30
BOUNDARY=1200
SCSISTOP=/usr/sbin/scsi-stop
LOGFILE=/tmp/scsi-stop.log

searchstr="disk_io:"
devaddr="(`/bin/ls -l $1 | /usr/bin/awk '{print($5 int($6/16))}'`)"

str=`/bin/grep "$searchstr" /proc/stat | devaddr="$devaddr" /usr/bin/awk -v 'RS= |\n' -F : '{ if($1==ENVIRON["devaddr"]) print($2) }'`
cooltime=0
stopped=0

while /bin/true; do
        /bin/sleep $PERIOD
        newstr=`/bin/grep "$searchstr" /proc/stat | devaddr="$devaddr" /usr/bin/awk -v 'RS= |\n' -F : '{ if($1==ENVIRON["devaddr"]) print($2) }'`
        if /usr/bin/[ "$newstr" = "$str" ]; then
                cooltime=$(($cooltime + $PERIOD))
                if /usr/bin/[ $cooltime -ge $BOUNDARY -a $stopped -eq 0 ]; then
                        $SCSISTOP $1
                        time=`/bin/date '+%b %e %H:%M:%S'`
                        /bin/echo "$time: Cooled down..." >> $LOGFILE
                        stopped=1
                fi
        else
                if /usr/bin/[ $cooltime -ne 0 ]; then
                        time=`/bin/date '+%b %e %H:%M:%S'`
                        /bin/echo "$time: Disk first used after $cooltime seconds" >> $LOGFILE
                fi
                cooltime=0
                str=$newstr
                stopped=0
        fi
done

----

(Last edited by pshdo on 6 May 2007, 11:10)

Hi,

I did a quick try before I start to configure a Linux box with the SDK. Using an UBUNTU live CD(ebian based), i downloaded the scsi-tools package, installed and tried to spin down the hard.
Executing the command gave simply the "File not found" error. Forcing, un-mounting the media doesn't helped.
In verbose mode said a bit more, and seeing the COMMAND NOT SUPPORTED (or something similar) string on the screen I gave up the further investigations.

scsi-spin: I have got bad luck.


root@wgt:/proc# scsi-spin -d -f /dev/sda
scsi-spin: /dev/sda is not a disk or generic SCSI device.

Bus 003 Device 003: ID 04b4:6830 Cypress Semiconductor Corp. USB-2.0 IDE Adapter

hello all smile managed to spin down my lacie usb hdd on the wl500gp with wr 0.9

cd /usr/bin
wget http://oleg.wl500g.info/bin/scsi-stop
chmod a+x scsi-stop

wink
we must now build some sort of automation for it cuz it works only on demand.

The discussion might have continued from here.