making SATA drives spin down?

I'd like to be able to make little-used SATA drives spin-down when idle for X minutes, and ideally then spin back up on access without timeouts or errors. Much like my USB-attached drives will do on their own. This is for drives that are used infrequently (eg, backup disks).

Something like SCSI's "camcontrol stop" would even be helpful, so I could script a "start" before any access. I couldn't find anything similar for ATA.

I looked through APM and ACPI docs as well as googled around without finding anything disk-specific. Anyone know if what I want to do is even possible?

(this is under FreeBSD 6.4-RELEASE though 7.x advice would be helpful too)

Thanks for any pointers
-omar
 
butcher said:
You can use `atacontrol spindown` in 7.1.

AHA! I found the manpage under 7.0-DEV on freebsd.org and that's exactly what I was looking for... I'll wait until FreeBSD 7.1-RELEASE comes out and upgrade to that, but answers my question exactly. I appreciate it!
-omar
 
spinup doesn't seem to work?

omarsidd said:
AHA! I found the manpage under 7.0-DEV on freebsd.org and that's exactly what I was looking for... I'll wait until FreeBSD 7.1-RELEASE comes out and upgrade to that, but answers my question exactly. I appreciate it!
-omar

I recently moved to 7.1-RELEASE (i386) on one of my workstations and after testing, sadly spindown doesn't work quite as seamlessly as I had hoped.

Set spindown on a SATAII drive, which spun down, but would not spin back up without a multitude of errors (tested for both mounted or unmounted filesystem). With a short spindown period (30sec) I couldn't get it to spin back up properly, tested by waking the disk with "ls" inside the mounted filesystem or "mount" on the unmounted filesystem.

Apparently the ops that were retrying were taking longer than the 30 seconds timeout, and the disk spun back down during all of this, then back up, etc. Logged errors like these:
Code:
Feb 25 15:35:22 mine kernel: ad16: Idle, spin down
Feb 25 15:35:22 mine kernel: ad16: drive spun down.
Feb 25 15:35:38 mine kernel: ad16: request while spun down, starting.
Feb 25 15:35:47 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:35:51 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:35:55 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:35:56 mine ntpd[759]: synchronized to 130.85.1.4, stratum 2
Feb 25 15:35:59 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:36:03 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:36:03 mine kernel: ad16: TIMEOUT - READ_DMA48 retrying (1 retry left) LBA=1264086511
Feb 25 15:36:08 mine kernel: ad16: Idle, spin down
Feb 25 15:36:12 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:36:16 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:36:20 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:36:24 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:36:28 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:36:28 mine kernel: ad16: TIMEOUT - READ_DMA48 retrying (0 retries left) LBA=1264086511
Feb 25 15:36:37 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:36:41 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:36:45 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:36:49 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:36:53 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:36:53 mine kernel: ad16: TIMEOUT - unknown CMD (0xe0) retrying (0 retries left)
Feb 25 15:37:02 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:37:06 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:37:10 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:37:14 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:37:18 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:37:18 mine kernel: ad16: FAILURE - READ_DMA48 timed out LBA=1264086511
Feb 25 15:37:18 mine kernel: g_vfs_done():ad16s1a[READ(offset=647212253184, length=16384)]error = 5
Feb 25 15:37:18 mine kernel: ad16: request while spun down, starting.
Feb 25 15:37:27 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:37:31 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
[...]
Feb 25 15:37:43 mine kernel: ad16: drive spun down.
Feb 25 15:37:48 mine kernel: ad16: Idle, spin down
[...shortened to fit in 1 post...]
Feb 25 15:39:00 mine kernel: ad16: TIMEOUT - unknown CMD (0xe0) retrying (0 retries left)
[...]
Feb 25 15:40:16 mine kernel: ad16: FAILURE - unknown CMD (0xe0) timed out
Feb 25 15:40:16 mine kernel: ad16: drive spun down.
Feb 25 15:40:52 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:40:56 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:41:00 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:41:04 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:41:08 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:41:08 mine kernel: ad16: FAILURE - READ_DMA48 timed out LBA=284034031
Feb 25 15:41:08 mine kernel: g_vfs_done():ad16s1a[READ(offset=145425383424, length=16384)]error = 5
Feb 25 15:41:25 mine kernel: ad16: request while spun down, starting.
Feb 25 15:41:58 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:42:02 mine kernel: ad16: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 15:42:06 mine kernel: ad16: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 15:42:10 mine kernel: ad16: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 15:42:14 mine kernel: ad16: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 15:42:14 mine kernel: ad16: WARNING - READ_DMA requeued due to channel reset LBA=303
Feb 25 15:42:29 mine kernel: agd_vfs_do1n6e(:) :deatda1c6hse1da[
Feb 25 15:42:29 mine kernel: READ(offset=114688, length=16384)]error = 6
Feb 25 15:42:40 mine kernel: ata8: [ITHREAD]
Feb 25 15:43:24 mine kernel: ata8: [ITHREAD]

I eventually did: atacontrol reinit, atacontrol detach, atacontrol attach, atacontrol reinit
on that drive's channel (last 2 log entries are from reinit) and found the drive had vanished (checking at each step) and I was unable to make it reappear without a reboot.

I tested on a 2nd drive with a longer spindown (45 up to 200 seconds) and in this case was able to get the drive to wake back up and complete it operation but only after several seconds and errors, eg:
Code:
Feb 25 16:13:47 mine kernel: ad12: Idle, spin down
Feb 25 16:13:47 mine kernel: ad12: drive spun down.
Feb 25 16:14:24 mine kernel: ad12: request while spun down, starting.
Feb 25 16:14:33 mine kernel: ad12: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 16:14:37 mine kernel: ad12: WARNING - SETFEATURES SET TRANSFER MODE taskqueue timeout - completing request directly
Feb 25 16:14:41 mine kernel: ad12: WARNING - SETFEATURES ENABLE RCACHE taskqueue timeout - completing request directly
Feb 25 16:14:45 mine kernel: ad12: WARNING - SETFEATURES ENABLE WCACHE taskqueue timeout - completing request directly
Feb 25 16:14:49 mine kernel: ad12: WARNING - SET_MULTI taskqueue timeout - completing request directly
Feb 25 16:14:49 mine kernel: ad12: TIMEOUT - WRITE_DMA retrying (1 retry left) LBA=1231
Feb 25 16:14:54 mine kernel: ad12: FAILURE - SETFEATURES SET TRANSFER MODE status=51<READY,DSC,ERROR> error=84<ICRC,ABORTED>
Feb 25 16:14:54 mine kernel: ad12: FAILURE - SETFEATURES ENABLE WCACHE status=51<READY,DSC,ERROR> error=4<ABORTED>
Feb 25 16:14:54 mine kernel: ad12: TIMEOUT - WRITE_DMA retrying (0 retries left) LBA=1231

In this case, the operations succeeded but with a many second lag (much longer than drive init or spindown/spinup on other systems takes) and a large number of warnings. I was able to get very simple ops (eg: ls for dirent already cached, or "pwd") to complete without error but all complex ones behaved this way ("ls -l")

I'd like to be able to spindown infrequently used drives and have them restart briskly when accessed (preferably without disk warnings logged by the kernel)

In practicality I'd keep the spindown timeout much higher (low # is just testing), but even so this looks unworkable...Any thoughts or advice?
 
I asked Soren Schmidt @freebsd who wrote atacontrol (but not the spindown part) and he commented that there are timing issues that are subtle and difficult to work around, no simple solution.

Anyone else have any ideas?
 
Code:
Feb 22 00:18:00 shadow kernel: ad6: Idle, spin down
Feb 22 00:18:01 shadow kernel: ad6: drive spun down.
Feb 22 04:05:01 shadow kernel: ad6: request while spun down, starting.
Feb 22 04:20:35 shadow kernel: ad6: Idle, spin down
Feb 22 04:20:35 shadow kernel: ad6: drive spun down.
Feb 22 23:57:00 shadow kernel: ad6: request while spun down, starting.
Feb 23 00:17:05 shadow kernel: ad6: Idle, spin down
Feb 23 00:17:05 shadow kernel: ad6: drive spun down.
Feb 23 04:05:09 shadow kernel: ad6: request while spun down, starting.
Feb 23 04:20:29 shadow kernel: ad6: Idle, spin down
Feb 23 04:20:30 shadow kernel: ad6: drive spun down.
Feb 23 23:57:00 shadow kernel: ad6: request while spun down, starting.
Feb 24 00:17:12 shadow kernel: ad6: Idle, spin down
Feb 24 00:17:12 shadow kernel: ad6: drive spun down.
Feb 24 04:05:08 shadow kernel: ad6: request while spun down, starting.
Feb 24 04:20:29 shadow kernel: ad6: Idle, spin down
Feb 24 04:20:29 shadow kernel: ad6: drive spun down.
Feb 24 23:57:01 shadow kernel: ad6: request while spun down, starting.
Feb 25 00:17:30 shadow kernel: ad6: Idle, spin down
Feb 25 00:17:30 shadow kernel: ad6: drive spun down.
Feb 25 04:05:08 shadow kernel: ad6: request while spun down, starting.
Feb 25 04:20:30 shadow kernel: ad6: Idle, spin down
Feb 25 04:20:30 shadow kernel: ad6: drive spun down.
Feb 25 23:57:00 shadow kernel: ad6: request while spun down, starting.
Feb 26 00:17:05 shadow kernel: ad6: Idle, spin down
Feb 26 00:17:05 shadow kernel: ad6: drive spun down.
Feb 26 04:05:09 shadow kernel: ad6: request while spun down, starting.
Feb 26 04:20:29 shadow kernel: ad6: Idle, spin down
Feb 26 04:20:29 shadow kernel: ad6: drive spun down.

FreeBSD 7.1-STABLE (Feb 17, 2009), Gigabyte MA-790X motherboard with SB600 SATA controller, and WD 500Gb SATAII drives. No problems at all set to:

Code:
root@shadow [/home/trev] $ atacontrol spindown ad6
ad6: spin down after 900 seconds idle
 
Hi omarsidd,
Please make sure your SMART power management(like ataidle or any other HARDWARE power management) is OFF. Harddrive power management does not inform freeBSD about state changes and it cause can create problem.
On my system atacontrol spindown was working fine.

Thanks
 
I created the following shell script file /usr/local/etc/rc.d/ad6.sh

Code:
#!/bin/sh

case "$1" in
start)
        echo "Spindown SATA disk ad6 after idle for 15 minutes."
        atacontrol spindown ad6 900 && dd if=/dev/ad6 of=/dev/null count=1 2> /dev/null &
        ;;
stop)
        echo "Spindown of SATA disk ad6 disabled."
        atacontrol spindown ad6 0 && dd if=/dev/ad6 of=/dev/null count=1 2> /dev/null
        ;;
status)
        atacontrol spindown ad6
        ;;
*)
        echo "Usage: `basename $0` {start|stop|status}" >&2
        exit 64
        ;;
esac
 
How do I poll the current status (spun up, or not)?

I've got my drives spinning down as desired, used ataidle.

Anyone know how to poll a drive to get its current spin status? The equivalent of linux "hdparm -C"? I've poked through atacontrol & ataidle man pages with no luck.
 
Back
Top