how to run hd-idle as service and power down unused disk drives?

Hi, I have bunch of WD drives, which seem to ignore hdparm -S command. It is actually a known bug of many WD drives. So I compiled hd-idle package from http://hd-idle.sourceforge.net/ (make & make install went fine) and it installed into /usr/local/sbin/hd-idle

When I invoke it from command line, it runs in the background and I see it running with ps ax and it does control drive power-downs.

me@opensuse:~/Downloads/hd-idle> sudo /usr/local/sbin/hd-idle -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300
[sudo] password for root:
me@opensuse:~/Downloads/hd-idle> ps ax | grep hd-idle
 1802 ?        S      0:00 /usr/local/sbin/hd-idle -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300
 1805 pts/4    S+     0:00 grep --color=auto hd-idle
me@opensuse:~/Downloads/hd-idle> sudo pkill hd-idle
me@opensuse:~/Downloads/hd-idle> ps ax | grep hd-idle
 1810 pts/4    R+     0:00 grep --color=auto hd-idle

But when I try to run it as service, it exits with code 0, but does not stay running and it does not power down disks. What is the difference between running command from .service file and from command line? Is there some hidden magic in maybe service type? Why it does not stay resident?

me@opensuse:~/Downloads/hd-idle> sudo cat /etc/systemd/system/hd-idle.service
[Unit]
Description=hd-idle spin down for HDDs

[Service]
Type=simple
ExecStart=/usr/local/sbin/hd-idle -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300

[Install]
WantedBy=multi-user.target

######
# so I try to run the service with exactly the same parameters:

me@opensuse:~/Downloads/hd-idle> sudo systemctl start hd-idle.service
me@opensuse:~/Downloads/hd-idle> sudo service hd-idle status
* hd-idle.service - hd-idle spin down for HDDs
   Loaded: loaded (/etc/systemd/system/hd-idle.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Tue 2019-12-03 13:03:38 CET; 38s ago
  Process: 1817 ExecStart=/usr/local/sbin/hd-idle -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300 (code=exited, status=0/SUCCESS)
 Main PID: 1817 (code=exited, status=0/SUCCESS)

Dec 03 13:03:38 server systemd[1]: Started hd-idle spin down for HDDs.

#######
# it returns exit code 0 like from command line, but it does not stay running:

me@opensuse:~/Downloads/hd-idle> ps ax | grep hd-idle
 1850 pts/4    R+     0:00 grep --color=auto hd-idle

Thank you for help.

Hi
Try adding;


Exec=/usr/bin/sh -c "/usr/local/sbin/hd-idle -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300"

You could also try forking…

Hello and thank you. Sh -c does not help though. So I looked into the man and found -d (debug) parameter, which prevents it becoming a daemon, so it stays running and displays statistics when invoked from cli. And it seems to be the trick. When I prevent it becoming a daemon, it stays as service :open_mouth: I’m not very happy with that, because I run it in debug mode now.

I hope someone comes up with better solution, but for now this is my hd-idle.service:

[Unit]
Description=hd-idle spin down for HDDs

[Service]
Type=simple
ExecStart=/usr/local/sbin/hd-idle -d -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300

[Install]
WantedBy=multi-user.target

The downside is, that it probably fills some journal (but not the defined /var/log/hd-idle.log) with debug messages every few seconds, but it works:

sudo systemctl status hd-idle.service
[sudo] password for root: 
● hd-idle.service - hd-idle spin down for HDDs
   Loaded: loaded (/etc/systemd/system/hd-idle.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-12-03 13:56:06 CET; 15min ago
 Main PID: 2071 (hd-idle)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/hd-idle.service
           └─2071 /usr/local/sbin/hd-idle -d -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300

Dec 03 14:09:52 server hd-idle[2071]: probing sda: reads: 1236222, writes: 23521832
Dec 03 14:09:52 server hd-idle[2071]: probing sdb: reads: 1306885, writes: 103720
Dec 03 14:09:52 server hd-idle[2071]: probing sdc: reads: 463606, writes: 11648
Dec 03 14:09:52 server hd-idle[2071]: probing sdd: reads: 16982, writes: 112
Dec 03 14:09:52 server hd-idle[2071]: probing sdf: reads: 23479974, writes: 45544
Dec 03 14:09:52 server hd-idle[2071]: probing sde: reads: 16125, writes: 72
Dec 03 14:09:52 server hd-idle[2071]: probing sdg: reads: 12516, writes: 64
Dec 03 14:09:52 server hd-idle[2071]: probing sda: reads: 1236222, writes: 23521832
Dec 03 14:09:52 server hd-idle[2071]: probing sdb: reads: 1306885, writes: 103720
Dec 03 14:09:52 server hd-idle[2071]: probing sdc: reads: 463606, writes: 11648

Hi
There is a patch… have a look here;
https://build.opensuse.org/package/show/home:seife:testing/hd-idle

Hi, nice find, thank you! I missed this one. I took a look at the patch and it does the same thing as debug parameter (does not call daemonize() ) when specified -n parameter, but without the extra debug output :slight_smile: I have not tested it yet, but I believe it will work, there’s even precompiled rpm, so probably no need to create .service file manually. Cool.

Hi, thank you again for help, I added the repo and hd-idle got installeg using zypper :slight_smile: It does not create hd-idle service in /etc/systemd/system/hd-idle.service though, but once executed with -n parameter, it does not flood journal with debug messages anymore.
This /etc/systemd/system/hd-idle.service works:

[Unit]
Description=hd-idle spin down for HDDs

[Service]
Type=simple
ExecStart=/usr/sbin/hd-idle **-n** -l /var/log/hd-idle.log -i 0 -a /dev/sdb -i 300 -a /dev/sdc -i 300 -a /dev/sdd -i 300 -a /dev/sde -i 300 -a /dev/sdf -i 300

[Install]
WantedBy=multi-user.target

In case someone (or me in the future) is interested, here are step by step instructions:

sudo zypper ar -cfp 100 https://download.opensuse.org/repositories/home:seife:testing/Leap_15.1/home:seife:testing.repo
sudo zypper refresh
sudo zypper install hd-idle
sudo nano /etc/systemd/system/hd-idle.service
#pasted the content from above
sudo systemctl daemon-reload
sudo systemctl enable hd-idle
sudo systemctl start hd-idle
sudo systemctl status hd-idle

Solved :wink:

Hi
There is one little funny I’m looking at with the code, the chdir(“/”) part as it throws a warning on Tumbleweed… but it does seem to work, the version is 1.05 as apposed to the repo version which is 1.04. Hopefully get a further chance to look at it this evening…

Hi
I’ve pushed an updated and working package with systemd service working and also the option to use YaST sysconfig editor to set your options…

https://build.opensuse.org/request/show/754207

If it gets accepted, you will need to remove your systemd service file and the installed binary in /usr/local/sbin…

Hi, thank you for your time, it would be nice to have the “latest” version in opensuse repo. I have not noticed the chdir warning, maybe I’m blind, maybe only tumbleweed is affected.
Maybe you are aware, that there is actually a more recent fork actively developed with more fixes https://github.com/adelolmo/hd-idle, I have not tested it, but why not patch this one? Thank you for your work, wish I could do it, but my c skills are limited almost to hello world :wink:

Btw. the version 1.5 compiled from source installs into /usr/local/sbin (make install), which I have deleted already, but the opensuse v1.4 installs into /usr/sbin, so I believe your update will work fine. If it overwrites the .service file, I will have to move the parameters to the newly proposed /etc/sysconfig/hd-idle, right?

Hi
Your service file is in /etc/systemd/system? If so it should override the one in /usr/lib/systemd/system. But yes, remove your one and add your options via YaST sysconfig editor.

That other one is written in go… not sure why folks want to re-invent the wheel, maybe a learning experience for the fork…? I have very little c experience, mainly from packaging and my goto folks on IRC :wink:

No need to create your own service. hd-idle comes with a nice one:

erlangen:~ # systemctl cat hd-idle
# **/usr/lib/systemd/system/hd-idle.service**
[Unit]
Description=hd-idle disk spindown service

[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/hd-idle
Environment=TERM=linux
ExecStart=/usr/bin/sh -c "/usr/sbin/hd-idle ${HD_IDLE_OPTS}"

[Install]
WantedBy=multi-user.target
erlangen:~ # 

  • To enable and start the service run ‘systemctl enable --now hd-idle’.
  • Use ‘yast2 sysconfig’ to modify options.

I have removed hd-idle, reinstalled again and indeed, it comes with one :open_mouth: Thank you for sharing steps how to activate it, now I know how to do that correctly :slight_smile: Yast is very convenient tool, but I try to avoid it, because it is opensuse only, and if you get used to it, it’s so easy to get lost on other distros. Opensuse is my main preference, but I use ubuntu and centos on some other boxes too.

I see, thanks for sharing. I would prefer the c one too, I don’t know about go, but the memory footprint of c binaries is really small and they are nearly as fast as assembly, so I like it.

Btw. I don’t know if it’s problem with the new hd-idle 1.05 version, but -n seems to be same as debug, it floods journalctl with debug messages again. I’m not sure if I have not noticed before, maybe 1.04 did that too?

Dec 14 14:07:06 server sh[25751]: probing sda: reads: 53012, writes: 0
Dec 14 14:07:06 server sh[25751]: probing sdb: reads: 544842, writes: 6168
Dec 14 14:07:06 server sh[25751]: probing sdc: reads: 29029346, writes: 16312
Dec 14 14:07:06 server sh[25751]: probing sdd: reads: 41754, writes: 184
Dec 14 14:07:06 server sh[25751]: probing sde: reads: 75562018, writes: 3416
Dec 14 14:07:06 server sh[25751]: probing sdf: reads: 199018811, writes: 22480
Dec 14 14:07:06 server sh[25751]: probing sdg: reads: 24232, writes: 64
Dec 14 14:07:36 server sh[25751]: probing sda: reads: 53012, writes: 0
Dec 14 14:07:36 server sh[25751]: probing sdb: reads: 544842, writes: 6168
Dec 14 14:07:36 server sh[25751]: probing sdc: reads: 29029346, writes: 16312
Dec 14 14:07:36 server sh[25751]: probing sdd: reads: 41754, writes: 184
Dec 14 14:07:36 server sh[25751]: probing sde: reads: 75562018, writes: 3416
Dec 14 14:07:36 server sh[25751]: probing sdf: reads: 199018811, writes: 22480
Dec 14 14:07:36 server sh[25751]: probing sdg: reads: 24232, writes: 64

Btw. how do I find out, what version of hd-idle (or other package) I have currently installed, when it does not have --version option? I see 1.05 only at openSUSE Software

Hi
Use zypper to see the version installed…


zypper if hd-idle

Thank you for quick reply, it works.

@malcolmlewis, do you have any solution to that redundant debug output to journalctl with -n?

Hi
Well it looks like it’s all or nothing…

If you add LogLevelMax=5 to the systemd service it will suppress, setting to 6 (debug/info) will show output…


cat /usr/lib/systemd/system/hd-idle.service 

[Unit]
Description=hd-idle disk spindown service

[Service]
LogLevelMax=5
Type=simple
EnvironmentFile=-/etc/sysconfig/hd-idle
Environment=TERM=linux
ExecStart=/usr/bin/sh -c "/usr/sbin/hd-idle ${HD_IDLE_OPTS}"

[Install]
WantedBy=multi-user.target

Edit as required then reload the systemd daemon and restart your service;


systemctl stop hd-idle
vi /usr/lib/systemd/system/hd-idle.service
systemctl daemon-reload
systemctl start hd-idle
systemctl status hd-idle
journalctl -f

Logging is broken for version from repo home_seife_testing. I switched to Install package home:X0F:HSF / hd-idle removed and installed: zypper rm hd-idle; zypper in hd-idle:

erlangen:~ # zypper if hd-idle
Loading repository data...
Reading installed packages...


Information for package hd-idle:
--------------------------------
Repository     : Hackeurs Sans Frontières (openSUSE_Tumbleweed)
Name           : hd-idle                                       
Version        : 1.05-1.23                                     
Arch           : x86_64                                        
Vendor         : obs://build.opensuse.org/home:X0F             
Installed Size : 38.4 KiB                                      
Installed      : Yes                                           
Status         : up-to-date                                    
Source package : hd-idle-1.05-1.23.src                         
Summary        : Spin down external harddisks                  
Description    :                                               
    hd-idle is a utility program for spinning-down external disks after a period of idle time. Since most external IDE disk enclosures don't support setting the IDE idle timer, a program like hd-idle is required to spin down idle disks automatically.

erlangen:~ # 

Configuration is now done at /etc/default/hd-idle. Logging is again what users presumably want to have:

erlangen:~ # journalctl -u hd-idle.service --since 20:45
-- Logs begin at Sat 2019-11-23 19:19:51 CET, end at Sat 2019-12-14 21:14:45 CET. --
Dec 14 20:45:32 erlangen systemd[1]: Stopping hd-idle disk spindown service...
Dec 14 20:45:32 erlangen systemd[1]: hd-idle.service: Succeeded.
Dec 14 20:45:32 erlangen systemd[1]: Stopped hd-idle disk spindown service.
Dec 14 20:45:32 erlangen systemd[1]: Started hd-idle disk spindown service.
Dec 14 20:45:32 erlangen hd-idle[21718]: hd-idle starting in nodaemon mode
Dec 14 20:45:32 erlangen hd-idle[21718]:   default timeout: 600
Dec 14 21:01:32 erlangen hd-idle[21718]: spindown: sda
erlangen:~ # 

Thank you, I have added LogLevelMax=5, followed all the steps, but it ignores the directive somehow and still dispays debug logs in here.

Thank you, Karl. We have indeed two different hd-idle “1.05” versions now:

Information for package hd-idle:
--------------------------------
Repository     : testing (Leap_15.1)                
Name           : hd-idle                            
Version        : 1.05-lp151.1.1                     
Arch           : x86_64                             
Vendor         : obs://build.opensuse.org/home:seife
Installed Size : 37.9 KiB                           
Installed      : Yes                                
Status         : up-to-date                         
Source package : hd-idle-1.05-lp151.1.1.src         
Summary        : Utility to spin down idle disk(s)  
Description    :                                    
    Utility program for spinning-down external disks after a period of idle time.
    Since most external IDE disk enclosures don't support setting the IDE idle
    timer, a program like hd-idle is required to spin down idle disks automatically.

The X0F:AHSF looks like Tumbleweed only, I’m on LEAP 15.1 on this particular machine and I have no clue what could possibly break. I’m not a big expert, so it is usually faster to fix broken opensuse by reinstalling it, which is what I cannot do it on this remote machine. What is the clever way to pick only the hd-idle package from this repo and ignore the rest? I mean better than downloading the binary rpm via wget and installing it from local file.

Thank you both for valueable help, maybe malcolm could fix the logging at home seife?:wink:

Hi
I can’t duplicate here on Tumbleweed… only system that has a spinning disk in it…

I started it yesterday morning and just one entry…


Dec 14 07:58:29 grover systemd[1]: Started hd-idle disk spindown service.

Can you try with just one disk to test.

Hi, I will try it later today, now I’m going out for a while. Btw. I’m using “sdb” name instead of “/dev/sdb”, because one of the versions I tried had problems with the latter, it looked like it was working, but actually was not spinning down the disks and it wasn’t also writing anything into the logs. Maybe that’s why you can’t reproduce?

In the meantime I downloaded the rpm from X0F repo via wget and it looks like it works. Only it ignores options in yast config, I had to edit directly /etc/default/hd-idle. I cannot confirm the disks are really off though:

Dec 15 15:31:47 server hd-idle[21320]:   disk: sdf timeout: 300
Dec 15 15:31:47 server hd-idle[21320]:   disk: sde timeout: 300
Dec 15 15:31:47 server hd-idle[21320]:   disk: sdd timeout: 300
Dec 15 15:31:47 server hd-idle[21320]:   disk: sdc timeout: 300
Dec 15 15:31:47 server hd-idle[21320]:   disk: sdb timeout: 300
Dec 15 15:31:47 server hd-idle[21320]:   default timeout: 0
Dec 15 15:36:47 server hd-idle[21320]: spindown: sdb
Dec 15 15:36:47 server hd-idle[21320]: spindown: sdc
Dec 15 15:36:52 server hd-idle[21320]: spindown: sdd
Dec 15 15:36:53 server hd-idle[21320]: spindown: sde
Dec 15 15:36:59 server hd-idle[21320]: spindown: sdf

Checked operation of disks and found that defaults work as advertised. The only HDD sda indeed spins down when idle for 10 minutes:

erlangen:~ # hdparm -C /dev/sda

/dev/sda:
 drive state is:  standby

erlangen:~ # journalctl -b -u hd-idle.service 
-- Logs begin at Sat 2019-11-23 19:19:51 CET, end at Sun 2019-12-15 20:43:51 CET. --
Dec 15 18:28:10 erlangen systemd[1]: Started hd-idle disk spindown service.
Dec 15 18:28:10 erlangen hd-idle[1059]: hd-idle starting in nodaemon mode
Dec 15 18:28:10 erlangen hd-idle[1059]:   default timeout: 600
Dec 15 18:39:10 erlangen hd-idle[1059]: spindown: sda
erlangen:~ #