Last mod: 2026.03.07
Linux HDD spin down configuration
Instructions for configuring a Linux system to spin down an HDD after a specified period of inactivity. The following description presents one of at least several possible methods for spinning down idle HDD drives. The advantage of this method, however, is that it should work with drives connected not only via SATA but also via USB.
Prerequisites
The instructions have been tested on a Raspberry Pi 4 running Debian GNU/Linux 12 (Bookworm) with a disk connected via USB3.
Install packages:
sudo apt update
sudo apt install -y hdparm sysstat bc
Scripts
disk-monitor.sh
Create file /usr/local/bin/disk-monitor.sh:
vi /usr/local/bin/disk-monitor.sh
with body:
#!/bin/bash
# Skrypt do monitorowania aktywności dysku /dev/sda
# Jeśli dysk jest nieużywany przez 60 sekund, wyłącza go do stanu uśpienia
DISK="/dev/sda"
IDLE_TIMEOUT=3600
LAST_ACTIVITY_FILE="/tmp/disk_activity_timestamp"
CHECK_INTERVAL=5
# Log file
LOG_FILE="/var/log/disk-monitor.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# Inicjalizacja
log_message "Uruchamianie monitora dysku dla $DISK"
while true; do
# Sprawdzenie aktualności dysku poprzez iostat
# Odczytujemy liczbę operacji I/O
CURRENT_IO=$(cat /proc/diskstats | grep -w sda | awk '{print $1}')
# Jeśli plik z ostatnią aktywnością nie istnieje, go tworzymy
if [ ! -f "$LAST_ACTIVITY_FILE" ]; then
echo "$(date +%s)" > "$LAST_ACTIVITY_FILE"
log_message "Utworzono plik timestamp"
fi
# Odczytujemy ostatni timestamp
LAST_TIMESTAMP=$(cat "$LAST_ACTIVITY_FILE")
CURRENT_TIMESTAMP=$(date +%s)
TIME_IDLE=$((CURRENT_TIMESTAMP - LAST_TIMESTAMP))
# Sprawdzamy czy dysk ma aktywność
# Używamy iostat do sprawdzenia rzeczywistej aktywności
if command -v iostat &> /dev/null; then
# Sprawdzenie przy użyciu iostat
IO_PERCENT=$(iostat -x 1 2 | grep sda | tail -1 | awk '{print $4}')
if (( $(echo "$IO_PERCENT > 0" | bc -l) )); then
echo "$(date +%s)" > "$LAST_ACTIVITY_FILE"
log_message "Aktywność dysku wykryta - IO: $IO_PERCENT%"
fi
else
# Fallback - jeśli iostat nie dostępny, sprawdzamy /proc/diskstats
CURRENT_READS=$(cat /proc/diskstats | grep -w sda | awk '{print $4}')
LAST_READS=$(cat "$LAST_ACTIVITY_FILE.reads" 2>/dev/null || echo "0")
if [ "$CURRENT_READS" != "$LAST_READS" ]; then
echo "$(date +%s)" > "$LAST_ACTIVITY_FILE"
echo "$CURRENT_READS" > "$LAST_ACTIVITY_FILE.reads"
log_message "Aktywność dysku wykryta - odczyty: $CURRENT_READS"
else
echo "$CURRENT_READS" > "$LAST_ACTIVITY_FILE.reads"
fi
fi
# Aktualizujemy czas bezczynności
LAST_TIMESTAMP=$(cat "$LAST_ACTIVITY_FILE")
CURRENT_TIMESTAMP=$(date +%s)
TIME_IDLE=$((CURRENT_TIMESTAMP - LAST_TIMESTAMP))
# Jeśli dysk jest nieaktywny przez IDLE_TIMEOUT sekund
if [ $TIME_IDLE -ge $IDLE_TIMEOUT ]; then
log_message "Dysk nieaktywny przez $TIME_IDLE sekund - wysyłanie do stanu uśpienia"
sudo hdparm -Y /dev/sda 2>> "$LOG_FILE"
if [ $? -eq 0 ]; then
log_message "Dysk $DISK pomyślnie uśpiony"
rm -f "$LAST_ACTIVITY_FILE"
else
log_message "BŁĄD: Nie udało się uśpić dysku $DISK"
fi
fi
sleep $CHECK_INTERVAL
done
Two important parameters that must be configured for your disk:
- DISK="/dev/sda" - specify the HDD disk to be checked and stopped
- IDLE_TIMEOUT=3600 - time in seconds after which it will be stopped due to inactivity
Add execution permissions:
sudo chmod +x /usr/local/bin/disk-monitor.sh
disk-monitor.service
Create file disk-monitor.service:
sudo vi /etc/systemd/system/disk-monitor.service
with body:
[Unit]
Description=HDD activity monitor and sleep service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/disk-monitor.sh
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=disk-monitor
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target
Add execution permissions:
sudo chmod 644 /etc/systemd/system/disk-monitor.service
Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable disk-monitor.service
sudo systemctl start disk-monitor.service
Problems
In case of problems, check using the following command whether the disk is stopping programmatically:
sudo hdparm -Y /dev/sda