toy around with explicitly spinning down the hard drive during shutdown

abandon the concept. it requires a systemd rebuild, and therefore
almost all of userspace. not worth it yet. maybe buy a powered hub.
This commit is contained in:
Colin 2022-05-18 10:40:28 +00:00
parent 32e00dac9d
commit e68ca3d600
5 changed files with 75 additions and 0 deletions

View File

@ -66,4 +66,37 @@
# ondemand power scaling keeps the cpu at low frequency when idle, and sets to max frequency
# when load is detected. (v.s. the "performance" default, which always uses the max frequency)
powerManagement.cpuFreqGovernor = "ondemand";
# XXX colin: this allows one to `systemctl halt` and then not remove power until the HDD has spun down.
# however, it doesn't work with reboot because systemd will spin the drive up again to read its reboot bin.
# a better solution would be to put the drive behind a powered USB hub (or get a SSD).
systemd.services.diskguard = {
description = "Safely power off spinning media";
before = [ "shutdown.target" ];
wantedBy = [ "sysinit.target" ];
# old (creates dep loop, but works)
# before = [ "systemd-remount-fs.service" "shutdown.target" ];
# wantedBy = [ "systemd-remount-fs.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.coreutils}/bin/true";
ExecStop = with pkgs; writeScript "diskguard" ''
#!${bash}/bin/bash
if ${procps}/bin/pgrep nixos-rebuild ;
then
exit 0 # don't halt drives unless we're actually shutting down. maybe better way to do this (check script args?)
fi
# ${coreutils}/bin/sync
# ${util-linux}/bin/mount -o remount,ro /nix/store
# ${util-linux}/bin/mount -o remount,ro /
# -S 1 retracts the spindle after 5 seconds of idle
# -B 1 spins down the drive after <vendor specific duration>
${hdparm}/sbin/hdparm -S 1 -B 1 /dev/sda
# TODO: monitor smartmonctl until disk is idle? or try hdparm -Y
# ${coreutils}/bin/sleep 20
# exec ${util-linux}/bin/umount --all -t ext4,vfat,ext2
'';
};
};
}

View File

@ -32,6 +32,7 @@
pkgs.file
pkgs.git
pkgs.gptfdisk
pkgs.hdparm
pkgs.htop
pkgs.iftop
pkgs.iotop
@ -46,6 +47,7 @@
pkgs.parted
pkgs.python3
pkgs.ripgrep
pkgs.smartmontools
pkgs.socat
pkgs.sudo
pkgs.telnet

View File

@ -6,6 +6,7 @@
# nix show-config
# nix eval --raw <expr> => print an expression. e.g. nixpkgs.raspberrypifw prints store path to the package
# nix-option ## query options -- including their SET VALUE; similar to search: https://search.nixos.org/options
# nixos-rebuild switch --upgrade ## pull changes from the nixos channel (e.g. security updates) and rebuild
{ config, lib, modulesPath, pkgs, specialArgs, options }:
@ -33,6 +34,8 @@ in
pleroma = super.callPackage ./pkgs/pleroma { };
# jackett doesn't allow customization of the bind address: this will probably always be here.
jackett = self.callPackage ./pkgs/jackett { pkgs = super; };
# fix abrupt HDD poweroffs as during reboot. patching systemd requires rebuilding nearly every package.
# systemd = import ./pkgs/systemd { pkgs = super; };
#### nixos-unstable packages
# gitea: 1.16.5 contains a fix which makes manual user approval *actually* work.

View File

@ -0,0 +1,28 @@
diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c
index 2c3cbec02c..8eef305578 100644
--- a/src/shutdown/shutdown.c
+++ b/src/shutdown/shutdown.c
@@ -603,6 +603,7 @@ int main(int argc, char *argv[]) {
execv(args[0], (char * const *) args);
/* execv failed (kexec binary missing?), so try simply reboot(RB_KEXEC) */
+ sleep(15);
(void) reboot(cmd);
_exit(EXIT_FAILURE);
}
@@ -614,6 +615,7 @@ int main(int argc, char *argv[]) {
_fallthrough_;
case RB_AUTOBOOT:
+ sleep(15);
(void) reboot_with_parameter(REBOOT_LOG);
log_info("Rebooting.");
break;
@@ -630,6 +632,7 @@ int main(int argc, char *argv[]) {
assert_not_reached();
}
+ sleep(15);
(void) reboot(cmd);
if (errno == EPERM && in_container) {
/* If we are in a container, and we lacked

9
pkgs/systemd/default.nix Normal file
View File

@ -0,0 +1,9 @@
{ pkgs }:
(pkgs.systemd.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [
# give the HDD time to spin down before abruptly cutting power
./01-spindown-drive.patch
];
}))