From b42540c91786677b74ae856709adeef0702ab0c2 Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Tue, 3 Oct 2023 12:48:52 +0200 Subject: [PATCH] add hdparm to spin-down drives --- hosts/yodaNas/configuration.nix | 1 + hosts/yodaTab/configuration.nix | 1 + hosts/yodaTux/configuration.nix | 1 + hosts/yodaYoga/configuration.nix | 1 + modules/btrbk/default.nix | 26 ---------- modules/spin-down.nix | 84 ++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 modules/spin-down.nix diff --git a/hosts/yodaNas/configuration.nix b/hosts/yodaNas/configuration.nix index 60f83e0..97fa3cf 100644 --- a/hosts/yodaNas/configuration.nix +++ b/hosts/yodaNas/configuration.nix @@ -57,6 +57,7 @@ in #../../modules/ntfs.nix #../../modules/veracrypt.nix ../../modules/btrbk + ../../modules/spin-down.nix ]; networking.hostName = "yodaNas"; diff --git a/hosts/yodaTab/configuration.nix b/hosts/yodaTab/configuration.nix index 12bffe4..e3bd537 100644 --- a/hosts/yodaTab/configuration.nix +++ b/hosts/yodaTab/configuration.nix @@ -56,6 +56,7 @@ in ../../modules/ntfs.nix #../../modules/veracrypt.nix #../../modules/btrbk + #../../modules/spin-down.nix ]; networking.hostName = "yodaTab"; diff --git a/hosts/yodaTux/configuration.nix b/hosts/yodaTux/configuration.nix index 85523fd..4f586ad 100644 --- a/hosts/yodaTux/configuration.nix +++ b/hosts/yodaTux/configuration.nix @@ -56,6 +56,7 @@ in ../../modules/ntfs.nix #../../modules/veracrypt.nix #../../modules/btrbk + #../../modules/spin-down.nix ]; networking.hostName = "yodaTux"; diff --git a/hosts/yodaYoga/configuration.nix b/hosts/yodaYoga/configuration.nix index abd05b4..23df028 100644 --- a/hosts/yodaYoga/configuration.nix +++ b/hosts/yodaYoga/configuration.nix @@ -57,6 +57,7 @@ in #../../modules/ntfs.nix #../../modules/veracrypt.nix #../../modules/btrbk + #../../modules/spin-down.nix ]; networking.hostName = "yodaYoga"; diff --git a/modules/btrbk/default.nix b/modules/btrbk/default.nix index 839d271..32ac231 100644 --- a/modules/btrbk/default.nix +++ b/modules/btrbk/default.nix @@ -12,32 +12,6 @@ # Print generated systemd unit file # cat "$(systemctl show -P FragmentPath btrbk-.service)" - # TODO: Maybe the following is not necessary if using hd-idle anyways (!) - # TODO: Mount/Unmount backup drive - # Example1: - # - https://github.com/oxalica/nixos-config/blob/1b18628afda9cecca0bc8c348b91e3ae6ab56905/nixos/invar/btrbk.nix#L55 - # - https://github.com/oxalica/nixos-config/blob/1b18628afda9cecca0bc8c348b91e3ae6ab56905/nixos/invar/btrbk.nix#L64 - # Example2: - # - https://github.com/emmanuelrosa/erosanix/blob/master/modules/btrbk.nix#L35-L42C7 - - # Spin down (unmounted/inactive) HDD disk. - # Inspired by https://www.reddit.com/r/NixOS/comments/751i5t/comment/do3f3l7/ - # -# environment.systemPackages = with pkgs; [ -# hd-idle -# ]; -# systemd.services.hd-idle = { -# description = "Spin down inactive HDD"; -# wantedBy = [ "multi-user.target" ]; -# serviceConfig = { -# Type = "simple"; -# # Options: -# # -a : Select disk for subsequent parameters. -# # -i 180: Spin down after 2 minutes (180 seconds) of inactivity. -# ExecStart = "${pkgs.hd-idle}/bin/hd-idle -a /dev/disk/by-id/XXX-XXX-XXX -i 180"; # TODO make disk id configurable -# }; -# }; - services.btrbk = { extraPackages = [ pkgs.lz4 ]; # Lowest scheduling priority. diff --git a/modules/spin-down.nix b/modules/spin-down.nix new file mode 100644 index 0000000..748f42d --- /dev/null +++ b/modules/spin-down.nix @@ -0,0 +1,84 @@ +{ config, pkgs, ... }: + +# hdparm - get/set SATA/IDE device parameters +# -q Handle the next option quietly, suppressing normal output (but not error messages). +# -I Print device information. +# -C Check the current IDE power mode status: +# unknown (drive does not support this command) +# active/idle (normal operation) +# standby (low power mode, drive has spun down) +# sleeping (lowest power mode, drive is completely shut down) +# -S Set the standby (spindown) timeout for the drive. +# The timeout specifies how long to wait in idle (with no disk activity) before turning off the motor to save power. +# The value of 0 disables spindown, +# the values from 1 to 240 specify multiples of 5 seconds +# and values from 241 to 251 specify multiples of 30 minutes. +# -y Force an IDE drive to immediately enter the low power consumption standby mode, usually causing it to spin down. + +# Get power status: +# sudo hdparm -C /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1 +# #=> drive state is: active/idle +# +# Spin down after 2 minutes (120s/5 = 24): +# sudo hdparm -S 24 /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1 # 4tb1 +# sudo hdparm -S 24 /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WCC4N1173157 # 3tb1 +# sudo hdparm -S 24 /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WMC4N0564095 # 3tb2 +# #=> setting standby to 24 (2 minutes) +# +# ... after >> 2 minutes ... +# +# Query disk without waking it up: +# https://wiki.archlinux.org/title/hdparm#Querying_the_status_of_the_disk_without_waking_it_up +# sudo smartctl -i -n standby /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1 +# #=> Device is in STANDBY mode, exit(2) +# +# Get power status: +# sudo hdparm -C /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1 +# sudo hdparm -C /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WCC4N1173157 +# sudo hdparm -C /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WMC4N0564095 +# #=> drive state is: standby + +# Power savings. +# With 12tb1, 3tb1, 3tb2 spinning and 4tb1 spun-down: 26.1 W +# With 12tb1 spinning and 3tb1, 3tb2, 4tb1 spun-down: 19.8 W +# -> WD30EFRX measured idle spinning vs standby = +3.15 W +# -> WD30EFRX advertised idle spinning vs unplugged = +3.0 W + +# See also: Systemd service to spin down after boot. https://wiki.archlinux.org/title/hdparm#Putting_a_drive_to_sleep_directly_after_boot + +# TODO: For external (USB-)disks, use `hd-idle`. +# https://www.reddit.com/r/NixOS/comments/751i5t/comment/do3f3l7/ +# # Options: +# # -a : Select disk for subsequent parameters. +# # -i 180: Spin down after 2 minutes (180 seconds) of inactivity. +# ExecStart = "${pkgs.hd-idle}/bin/hd-idle -a /dev/disk/by-id/XXX-XXX-XXX -i 180"; + +{ + environment.systemPackages = with pkgs; [ + hdparm + ]; + systemd.services."hdparm-4tb1" = { + description = "Spin down inactive HDD"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.hdparm}/bin/hdparm -S 24 /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1"; + }; + }; + systemd.services."hdparm-3tb1" = { + description = "Spin down inactive HDD"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.hdparm}/bin/hdparm -S 24 /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WCC4N1173157"; + }; + }; + systemd.services."hdparm-3tb2" = { + description = "Spin down inactive HDD"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.hdparm}/bin/hdparm -S 24 /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WMC4N0564095"; + }; + }; +}