grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / hardware / sata.nix
blob81592997d6e3dd5ce95d589e71ad7dae7d6dd996
1 { config, lib, pkgs, ... }:
2 let
3   inherit (lib) mkEnableOption mkIf mkOption types;
5   cfg = config.hardware.sata.timeout;
7   buildRule = d:
8     lib.concatStringsSep ", " [
9       ''ACTION=="add"''
10       ''SUBSYSTEM=="block"''
11       ''ENV{ID_${lib.toUpper d.idBy}}=="${d.name}"''
12       ''TAG+="systemd"''
13       ''ENV{SYSTEMD_WANTS}="${unitName d}"''
14     ];
16   devicePath = device:
17     "/dev/disk/by-${device.idBy}/${device.name}";
19   unitName = device:
20     "sata-timeout-${lib.strings.sanitizeDerivationName device.name}";
22   startScript =
23     pkgs.writeShellScript "sata-timeout.sh" ''
24       set -eEuo pipefail
26       device="$1"
28       ${pkgs.smartmontools}/bin/smartctl \
29         -l scterc,${toString cfg.deciSeconds},${toString cfg.deciSeconds} \
30         --quietmode errorsonly \
31         "$device"
32     '';
36   meta.maintainers = with lib.maintainers; [ peterhoeg ];
38   options.hardware.sata.timeout = {
39     enable = mkEnableOption "SATA drive timeouts";
41     deciSeconds = mkOption {
42       example = 70;
43       type = types.int;
44       description = ''
45         Set SCT Error Recovery Control timeout in deciseconds for use in RAID configurations.
47         Values are as follows:
48            0 = disable SCT ERT
49           70 = default in consumer drives (7 seconds)
51         Maximum is disk dependant but probably 60 seconds.
52       '';
53     };
55     drives = mkOption {
56       description = "List of drives for which to configure the timeout.";
57       type = types.listOf
58         (types.submodule {
59           options = {
60             name = mkOption {
61               description = "Drive name without the full path.";
62               type = types.str;
63             };
65             idBy = mkOption {
66               description = "The method to identify the drive.";
67               type = types.enum [ "path" "wwn" ];
68               default = "path";
69             };
70           };
71         });
72     };
73   };
75   config = mkIf cfg.enable {
76     services.udev.extraRules = lib.concatMapStringsSep "\n" buildRule cfg.drives;
78     systemd.services = lib.listToAttrs (map
79       (e:
80         lib.nameValuePair (unitName e) {
81           description = "SATA timeout for ${e.name}";
82           wantedBy = [ "sata-timeout.target" ];
83           serviceConfig = {
84             Type = "oneshot";
85             ExecStart = "${startScript} '${devicePath e}'";
86             PrivateTmp = true;
87             PrivateNetwork = true;
88             ProtectHome = "tmpfs";
89             ProtectSystem = "strict";
90           };
91         }
92       )
93       cfg.drives);
95     systemd.targets.sata-timeout = {
96       description = "SATA timeout";
97       wantedBy = [ "multi-user.target" ];
98     };
99   };