20

Does anyone know if there is an elegant way to tell an external usb drive not to spin down after a period of inactivity? I've seen cron based solutions that write a file every minute, but nothing that smells of nice unixey elegance. There must be a hdparm, or scsi command that I can issue (usb drives are accessed via the sd driver in OpenBSD) to the drive to tell it to not sleep. I'm afraid that this is probably a feature built into the controller in the enclosure, and as such not much can change it aside from ripping the drive out of it's enclosure and plopping it directly in the machine, but I figured I would ask, on the off chance.

Ideally, I'm looking for an OpenBSD solution, but I know there are others out there w/the same problem so any solutions will be considered for the answer.

3
  • 1
    I'm just curious why you don't want the drive to spin down.
    – tshepang
    Jan 3, 2011 at 18:35
  • 3
    Well, for the moment, it's because I have that drive mounted via NFS on another machine, and if I boot machine #2 while the drive is spun down, it timesout, and the NFS partition doesn't mount.
    – gabe.
    Jan 4, 2011 at 2:31
  • 1
    Not letting the drive spin down can reduce its lifetime. I would consider addressing the timeout issue instead. I had a similar problem before with a backup NAS and using an automounter (such as autofs) ensured that the system would not timeout and only spin up the disks if the mountpoint is accessed (and auto-mounted).
    – unode
    Feb 16, 2012 at 22:43

6 Answers 6

13

Just my 2 cents...

It is more than true that spinning down the disks decreases their service life. Years of experience have shown that starting and stopping the disk motor causes far more fatigue than 24/7 spin. All my disks with big start/stop count have reallocated sectors and all my disks that spin 10 years 24/7 are (believe it or not) good as new. After all, disks are made for spinning not for idling, so if your priority is less fatigue than power consumption feel free to have your disks 24/7 spinning.

I have an external 2TB disk that spins down after 30 minutes of inactivity. The disk is meant to be powered on 24/7 for backing up purposes and acting as a small NAS attached to an Orange PI.

I used the following udev rule in

/etc/udev/rules.d

(It never worked as the spin down is in disks firmware)

SUBSYSTEM=="usb", TEST=="power/autosuspend" ATTR{power/autosuspend}="-1"

Although the disk supports the

hdparm -B

I wrote a small daemon process that can run at boot time in

/etc/rc.local

that writes 10 times in cicles the current date and time in a log file so the disk is always on. Feel free to modify as you like.

Command line options are: the target directory to write awake.log and (optionally) the time delay (default 300)

e.g.

/usr/sbin/disk_awake /mnt/some_disk/keep_alive 30

the code: (you can compile with gcc)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

int main(int argc, char* argv[])
{
FILE *fp=NULL;
pid_t process_id=0;
pid_t sid=0;
int secs=300;
char log_file[512];
time_t raw_time;
struct tm *time_info;
int ticks=0;
unsigned long step=1;

if (argc<2||argc>3)
{
 printf("Usage: %s target_directory [seconds]\n",argv[0]);
 exit(1);
}
if (strlen(argv[1])>500)
{
 printf("String length of target_directory is HUGE!\n");
 exit(1);
}
if (chdir(argv[1])<0)
{
 printf("Directory %s does not exist\n",argv[1]);
 exit(1);
}
strcpy(log_file,argv[1]);
strcat(log_file,"/awake.log");
if (!(fp=fopen(log_file,"w+")))
{
 printf("Could not open log file %s\n",log_file);
 exit(1);
}
if (!(argv[2]))
{
 printf("Delay argument not specified. Defaulting to 300 seconds\n");
 secs=300;
}
if (argv[2]&&(secs=atoi(argv[2]))<=0)
{
 printf("Could not parse delay option. Defaulting to 300 seconds\n");
 secs=300;
}
printf("Delay interval %d seconds\n",secs);
process_id=fork();
if (process_id<0)
{
printf("Could not fork()\n");
exit(1);
}
if (process_id>0)
{
printf("Started with pid %d\n", process_id);
exit(0);
}
umask(0);
sid=setsid();
if(sid<0)
{
printf("Could not setsid()\n");
exit(1);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
while (1)
{
if (ticks==10)
{
 fclose(fp);
 if (!(fp=fopen(log_file,"w+"))) exit(1);
 ticks=0;step++;
}
time(&raw_time);
time_info=localtime(&raw_time);
fprintf(fp,"%s %lu : %s","Step",step,asctime(time_info));
fflush(fp);
ticks++;
sleep(secs);
}
fclose(fp);
return(0);
}
2
  • 14
    Why the need for a special (C) program? Why not just a cron job... ` */15 * * * * date > /mnt/disk/.date` Jan 12, 2017 at 15:50
  • I am running a Lenovo T470p, external USB drive with an orico USB housing. I am booting from the USB, as soon as the standby starts, the device goes read only on wakeup. The udev.d configuration fixed the issue for me.
    – thst
    May 21, 2018 at 10:49
9

I have found that the following cronjob works for me.

*/5 * * * * /bin/touch /dev/sdb &>/dev/null

Obviously update it with the device name of your disk.

You can also vary the time based on how long your drive is idle before it powers down.

6

Yeah, it's generally built into the firmware. Some drive manufacturers provide an MS Windows based management tool that will allow you to modify various parameters, including disabling the "sleep" or spin down timer. If you have access to a Windows box it might be worth it to pursue that angle.

6

This solution (for Linux) from http://www.arrfab.net/blog/?p=107 has helped for a 1TB Seagate Portable drive which kept going to sleep:

# sdparm --clear=STANDBY /dev/sdc -S

The drive now is immediately responsive even when left idle for an hour. Didn't test yet whether the setting is saved across restarts etc, though.

3
  • any tip on doing this without sudo? Aug 23, 2014 at 0:57
  • 2
    I believe the link has changed to: arrfab.net/posts/2009/Jan/30/…
    – esm
    Oct 13, 2018 at 10:04
  • @AquariusPower You cannot modify hardware settings without root access. Periodic storage access (e.g. touching some file timestamp) is the best you can do without changing hardware settings. Nov 12, 2022 at 10:39
5

I see citations and questions, but not any direct suggestions for syntax, so adding in my answer despite one being accepted. The command(s) for elegantly de-activating sleep with hdparm (as requested) would be:

hdparm -S 0 /dev/sdx

or possibly ...

hdparm -B255 /dev/sdx

For what your drive supports and does not support, execute:

hdparm -I /dev/sdx

Run these at your own risk, but if your drive supports the first option, that completely disables sleep and would seem quite elegant to me. It could be that these options were not available in 2010, so if so, this should help with folks coming by!

3

The manual for the linux hdparm provides the following info:

-B  Query/set Advanced Power Management feature,
    if the drive supports it.
    A low value means aggressive  power  management
    and a high value means better performance.

    Possible settings range
    from values 1 through  127  (which  permit spin-down),
    and values 128 through 254 (which do not permit spin-down).

    The highest degree of  power  management
    is attained with a setting of 1,
    and the highest I/O performance with a setting of 254.

    A  value  of  255  tells hdparm to
    disable Advanced Power Management altogether on the drive
    (not all drives support disabling it, but  most do).

That being said, it's still not guaranteed that your drive enclosure will support relaying these instructions to the drive. The same reference mentions that being able to use hdparm with an enclosure at all is only possible with certain "newer (2008 and later)" models that support the SCSI-ATA Command Translation system, aka "SAT". I've yet to try doing this on anything but a recent cheap backup drive, an HP SimpleSave model. It seems to provide some limited power management functionality.

And of course this also assumes that OpenBSD's hdparm works in the same way. I am not at all knowledgeable in the ways of OpenBSD, so I can't help you there.

4
  • 2
    The OpenBSD equivalent of hdparm is atactl. But I don't know if it works on USB devices; atactl(8) is referenced by wd(4) (the IDE disk driver man page) but not by umass(4) (the USB storage driver man page). Jan 4, 2011 at 21:26
  • I'm going to play with this, though since usb drives mount using the /dev/sd* devices, I'm not sure wd and atactl apply. Time to do some reading/playing.
    – gabe.
    Jan 6, 2011 at 2:08
  • do you think hdparm could be used in a loop in some way without sudo to prevent sleeping? Aug 23, 2014 at 1:01
  • Do you know hdparam default value for -B [apm_setting] ?
    – jyz
    Sep 4, 2016 at 19:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .