I tried to check ZimaOS (v1.5.4) in quite simple setup:
PC, 4 disks: 2 SSD, 2 HDD, configured with 2 raid 1 (mirrors). HDDs are used for backup, big storage ect. It is important that those go to sleep. I set
Problem, HDDs from array are waking every 30 minutes (around every 20 and 50 minutes of hour), it means 48 times per day. That will end almost any disk in less than 3 years ![]()
Other had reported similar / that same problem: more than 2… examples: Hdd stanby not working , Disk Standby / Spin Down / Sleep doesn't work, disks being accessed 24/7 - no solution was proposed ![]()
My finding. There are 2 separate problems.
- Wrong configuration of SMART demon. It always wakes disks every hour or 30 minutes.
fix, add parameter “- standby” to DEVICESCAN in config file /ect/smartd.conf, then restart deamon
sudo sed -i ‘s/^DEVICESCAN$/DEVICESCAN -n standby/’ /etc/smartd.conf
sudo systemctl restart smartd
now you disk will wake every hour
- Bug in zimaos-local-storage.service
Background, storage service every hour check every defined storage array. It execute command like this:
mdadm -D /dev/md1
But this command WAKES disks, so to prevent this disk need to be checked. And here is a bug: Storage service sends command
hdparm -C /dev/md
There are 2 problems with this command. First, device /dev/md not exist, only md0 and md2 exists as storage arrays. Seconds even when checked /dev/md1 will not get status of drives, because array is not a drive.
Correct way, extract list of devices in array md1 (lsblk -e 7,252,43 -OJb ) executed by storage.service has this info), and check at least one of it drives it is in “Standby” mode, like:
hdparm -C /dev/sda
Unfortunately to fix it you need to fix compiled zimaos-local-storage - so please ZimaOS developers - make it happened.
Workarounds:
You can replace hdparm or mdadm command executed by zimaos-local-storage by simple tick:
mkdir /etc/sbin
sudo systemctl edit zimaos-local-storage
paste there:
[Service]
Environment=PATH=/etc/sbin:/usr/sbin:/usr/bin:/sbin:/bin
Reload and restart service:
sudo systemctl daemon-reload
sudo systemctl restart zimaos-local-storage
Now we need a “wraper” from mdadm that will not wake disk if not needed (please add your own storage number and disk list). It can be extended to allow disk reports at least every 3 days ect., but I hope it is only temporary and ZimaOs will be fixed soon.
create file ( nano /etc/sbin/madm ): and make it executable ( chmod +x /etc/sbin/mdadm )
#!/bin/bash
set -euo pipefail
REAL_MDADM="/usr/sbin/mdadm"
REAL_HDPARM="/usr/sbin/hdparm"
CACHE="/etc/sbin/mdadm_md1.txt"
LOCK="/etc/sbin/mdadm_md1.lock"
ARRAY="/dev/md1"
DISKS=("/dev/sda" "/dev/sdb")
is_md1_detail_call() {
# Akceptuj: mdadm -D /dev/md1 OR mdadm --detail /dev/md1
# oraz ewentualnie: mdadm -D --verbose /dev/md1 (z flagami pomiędzy)
local has_detail=0
local has_md1=0
for a in "$@"; do
case "$a" in
-D|--detail) has_detail=1 ;;
"$ARRAY") has_md1=1 ;;
esac
done
[[ $has_detail -eq 1 && $has_md1 -eq 1 ]]
}
disk_is_standby() {
# Zwraca 0 jeśli standby, 1 jeśli aktywny/nieznany
local d="$1"
local out
out="$($REAL_HDPARM -C "$d" 2>/dev/null || true)"
echo "$out" | grep -qi "drive state is:.*standby"
}
all_disks_standby() {
# 0 jeśli WSZYSTKIE są standby
for d in "${DISKS[@]}"; do
if ! disk_is_standby "$d"; then
return 1
fi
done
return 0
}
run_real_and_cache() {
# Uruchamia prawdziwy mdadm, zapisuje stdout+stderr do cache i odtwarza wynik (output+exitcode)
local tmp
tmp="$(mktemp /tmp/mdadm_md1.XXXXXX)"
set +e
"$REAL_MDADM" "$@" >"$tmp" 2>&1
local rc=$?
set -e
# atomowy zapis cache (ważne przy równoległych wywołaniach)
install -m 0644 "$tmp" "$CACHE"
cat "$tmp"
rm -f "$tmp"
return $rc
}
serve_cache_or_fallback() {
# Jeśli jest cache, zwróć go. Jeśli nie ma (pierwsze uruchomienie), wykonaj real mdadm (tak, obudzi)
if [[ -f "$CACHE" ]]; then
cat "$CACHE"
return 0
fi
# brak cache → nie mamy jak "udawać", więc robimy real call
run_real_and_cache "$@"
}
main() {
# Jeżeli to nie jest -D/--detail na /dev/md1 → przepuszczamy bez zmian
if ! is_md1_detail_call "$@"; then
exec "$REAL_MDADM" "$@"
fi
# blokada na czas decyzji + ewentualnego odświeżenia cache
mkdir -p "$(dirname "$LOCK")" 2>/dev/null || true
exec 9>"$LOCK"
flock -x 9
if all_disks_standby; then
# dyski śpią → nie budź, zwróć cache
serve_cache_or_fallback "$@"
exit $?
else
# dyski aktywne → można wykonać real mdadm i odświeżyć cache
run_real_and_cache "$@"
exit $?
fi
}
main "$@"