From 15dc4c195a9a488c03b826ab612881906791076e Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Thu, 23 Nov 2023 13:04:07 +0100 Subject: [PATCH] spin-down-hdd --- examples/case-esac.sh | 13 +++++++++++++ modules/spin-down-hdd.nix | 33 ++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 examples/case-esac.sh diff --git a/examples/case-esac.sh b/examples/case-esac.sh new file mode 100644 index 0000000..2b8fa5a --- /dev/null +++ b/examples/case-esac.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +x='some-test' + +case "${x}" in + *'_'*|*'-'*) + echo "The string contains _ or -" + ;; + *) + echo 'No pattern matched' + ;; +esac diff --git a/modules/spin-down-hdd.nix b/modules/spin-down-hdd.nix index 9bc0b45..f4117f6 100644 --- a/modules/spin-down-hdd.nix +++ b/modules/spin-down-hdd.nix @@ -54,11 +54,6 @@ # # -i 120: Spin down after 2 minutes (120 seconds) of inactivity. # ExecStart = "${pkgs.hd-idle}/bin/hd-idle -a /dev/disk/by-id/XXX-XXX-XXX -i 120"; -# Note about the `script` settings below. -# If the disk is spun-down (in standby mode): -# - The standby timeout has been set before already, otherwise it would be spinning. -# - Don't set the standby timeout again, as this will spin up the disk. - { lib, config, options, pkgs, modulesPath, ... }: with lib; let @@ -77,11 +72,6 @@ in }; config = mkIf (length cfg > 0) { - # TODO: Is this required or is it enough to use `${pkgs.hdparm}` in the systemd service script? - environment.systemPackages = with pkgs; [ - hdparm - ]; - # For each element (e.g. "ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1") in `cfg` create this config: # systemd.services."hdparm-ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CPF0N1" = { # description = ...; @@ -95,7 +85,28 @@ in wantedBy = [ "multi-user.target" ]; serviceConfig.Type = "oneshot"; script = '' - ${pkgs.hdparm}/bin/hdparm -C /dev/disk/by-id/${id} | ${pkgs.busybox}/bin/grep 'standby' || ${pkgs.hdparm}/bin/hdparm -S 24 /dev/disk/by-id/${id} + set -eu -o pipefail + # Get IDE power mode status and remove any whitespace characters for easier pattern matching. + result="$(${pkgs.hdparm}/bin/hdparm -C /dev/disk/by-id/${id} | ${pkgs.coreutils}/bin/tr -d '[:space:]')" + case "''${result}" in + *'/dev/disk/by-id/${id}:drivestateis:standby'*|*'/dev/disk/by-id/${id}:drivestateis:sleeping'*) + printf '%s\n' 'Disk is in standby or sleeping.' + # Don't set idle timeout as this would spin up the disk. + # It has already been set before, otherwise the disk would be spinning. + ;; + *'/dev/disk/by-id/${id}:drivestateis:active/idle'*) + printf '%s\n' 'Disk is active. Set idle timeout to 10 minutes.' + ${pkgs.hdparm}/bin/hdparm -S 24 /dev/disk/by-id/${id} + ;; + *'/dev/disk/by-id/${id}:drivestateis:unknown'*) + printf '%s\n' 'Disk is not supported by hdparm.' + exit 1 + ;; + *) + printf '%s%s\n' 'Unknown hdparm output: ' "''${result}" + exit 1 + ;; + esac ''; }; }) cfg);