diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4e0d3b77fe30..cf82e5035d9a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -144,6 +144,7 @@ ./services/hardware/acpid.nix ./services/hardware/amd-hybrid-graphics.nix ./services/hardware/bluetooth.nix + ./services/hardware/freefall.nix ./services/hardware/nvidia-optimus.nix ./services/hardware/pcscd.nix ./services/hardware/pommed.nix diff --git a/nixos/modules/services/hardware/freefall.nix b/nixos/modules/services/hardware/freefall.nix new file mode 100644 index 000000000000..6e6960bac491 --- /dev/null +++ b/nixos/modules/services/hardware/freefall.nix @@ -0,0 +1,62 @@ +{ config, lib, pkgs, utils, ... }: + +with lib; + +{ + + ###### interface + + options = with types; { + + services.freefall = { + + enable = mkOption { + default = false; + description = '' + Whether to protect HP/Dell laptop hard drives (not SSDs) in free fall. + ''; + type = bool; + }; + + devices = mkOption { + default = [ "/dev/sda" ]; + description = '' + Device paths to all internal spinning hard drives. + ''; + type = listOf string; + }; + + }; + + }; + + ###### implementation + + config = let + + cfg = config.services.freefall; + + mkService = dev: + assert dev != ""; + let dev' = utils.escapeSystemdPath dev; in + nameValuePair "freefall-${dev'}" + { description = "Free-fall protection for ${dev}"; + after = [ "${dev'}.device" ]; + wantedBy = [ "${dev'}.device" ]; + path = [ pkgs.freefall ]; + serviceConfig = { + ExecStart = "${pkgs.freefall}/bin/freefall ${dev}"; + Restart = "on-failure"; + Type = "forking"; + }; + }; + + in mkIf cfg.enable { + + environment.systemPackages = [ pkgs.freefall ]; + + systemd.services = listToAttrs (map mkService cfg.devices); + + }; + +} diff --git a/pkgs/os-specific/linux/freefall/default.nix b/pkgs/os-specific/linux/freefall/default.nix new file mode 100644 index 000000000000..9903cb5b963d --- /dev/null +++ b/pkgs/os-specific/linux/freefall/default.nix @@ -0,0 +1,42 @@ +{ stdenv, fetchurl }: + +stdenv.mkDerivation rec { + version = "3.18.3"; + name = "freefall-${version}"; + + src = fetchurl { + url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz"; + sha256 = "0ma2x68975xsi9kb15p0615nx9sm5ppb309kfdz7fgx9pg84q0hf"; + }; + + buildPhase = '' + cd Documentation/laptops + + # Default time-out is a little low, probably because the AC/lid status + # functions were never implemented. Because no-one still uses HDDs, right? + substituteInPlace freefall.c --replace "alarm(2)" "alarm(5)" + + cc -o freefall freefall.c + ''; + + installPhase = '' + mkdir -p $out/bin + install freefall $out/bin + ''; + + meta = with stdenv.lib; { + description = "Free-fall protection for spinning HP/Dell laptop hard drives"; + longDescription = '' + ATA/ATAPI-7 specifies the IDLE IMMEDIATE command with unload feature. + Issuing this command should cause the drive to switch to idle mode and + unload disk heads. This feature is being used in modern laptops in + conjunction with accelerometers and appropriate software to implement + a shock protection facility. The idea is to stop all I/O operations on + the internal hard drive and park its heads on the ramp when critical + situations are anticipated. This has no effect on SSD devices! + ''; + license = with licenses; gpl2; + platforms = with platforms; linux; + maintainers = with maintainers; [ nckx ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 79e33e9ac4a9..f9f8e0ad499a 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -8418,6 +8418,8 @@ let firejail = callPackage ../os-specific/linux/firejail {}; + freefall = callPackage ../os-specific/linux/freefall { }; + fuse = callPackage ../os-specific/linux/fuse { }; fxload = callPackage ../os-specific/linux/fxload { };