1 { config, lib, pkgs, ... }:
4 cfg = config.hardware.rasdaemon;
8 options.hardware.rasdaemon = {
10 enable = lib.mkEnableOption "RAS logging daemon";
12 record = lib.mkOption {
13 type = lib.types.bool;
15 description = "record events via sqlite3, required for ras-mc-ctl";
18 mainboard = lib.mkOption {
19 type = lib.types.lines;
21 description = "Custom mainboard description, see {manpage}`ras-mc-ctl(8)` for more details.";
26 # it should default to such values from
27 # /sys/class/dmi/id/board_[vendor|name]
28 # alternatively one can supply a script
29 # that returns the same format as above
31 script = <path to script>
35 # TODO, accept `rasdaemon.labels = " ";` or `rasdaemon.labels = { dell = " "; asrock = " "; };'
37 labels = lib.mkOption {
38 type = lib.types.lines;
40 description = "Additional memory module label descriptions to be placed in /etc/ras/dimm_labels.d/labels";
42 # vendor and model may be shown by 'ras-mc-ctl --mainboard'
44 product: To Be Filled By O.E.M.
46 # these labels are names for the motherboard slots
47 # the numbers may be shown by `ras-mc-ctl --error-count`
48 # they are mc:csrow:channel
49 DDR4_A1: 0.2.0; DDR4_B1: 0.2.1;
50 DDR4_A2: 0.3.0; DDR4_B2: 0.3.1;
54 config = lib.mkOption {
55 type = lib.types.lines;
58 rasdaemon configuration, currently only used for CE PFA
59 for details, read rasdaemon.outPath/etc/sysconfig/rasdaemon's comments
62 # defaults from included config
63 PAGE_CE_REFRESH_CYCLE="24h"
64 PAGE_CE_THRESHOLD="50"
69 extraModules = lib.mkOption {
70 type = lib.types.listOf lib.types.str;
72 description = "extra kernel modules to load";
73 example = [ "i7core_edac" ];
76 testing = lib.mkEnableOption "error injection infrastructure";
79 config = lib.mkIf cfg.enable {
83 enable = cfg.mainboard != "";
86 # TODO, handle multiple cfg.labels.brand = " ";
87 "ras/dimm_labels.d/labels" = {
88 enable = cfg.labels != "";
91 "sysconfig/rasdaemon" = {
92 enable = cfg.config != "";
96 environment.systemPackages = [ pkgs.rasdaemon ]
97 ++ lib.optionals (cfg.testing) (with pkgs.error-inject; [
103 boot.initrd.kernelModules = cfg.extraModules
104 ++ lib.optionals (cfg.testing) [
105 # edac_core and amd64_edac should get loaded automatically
106 # i7core_edac may not be, and may not be required, but should load successfully
114 boot.kernelPatches = lib.optionals (cfg.testing) [{
115 name = "rasdaemon-tests";
127 # i tried to set up a group for this
128 # but rasdaemon needs higher permissions?
129 # `rasdaemon: Can't locate a mounted debugfs`
131 # most of this taken from src/misc/
134 description = "the RAS logging daemon";
135 documentation = [ "man:rasdaemon(1)" ];
136 wantedBy = [ "multi-user.target" ];
139 StateDirectory = lib.optionalString (cfg.record) "rasdaemon";
141 ExecStart = "${pkgs.rasdaemon}/bin/rasdaemon --foreground"
142 + lib.optionalString (cfg.record) " --record";
143 ExecStop = "${pkgs.rasdaemon}/bin/rasdaemon --disable";
144 Restart = "on-abort";
146 # src/misc/rasdaemon.service.in shows this:
147 # ExecStartPost = ${pkgs.rasdaemon}/bin/rasdaemon --enable
148 # but that results in unpredictable existence of the database
149 # and everything seems to be enabled without this...
152 ras-mc-ctl = lib.mkIf (cfg.labels != "") {
153 description = "register DIMM labels on startup";
154 documentation = [ "man:ras-mc-ctl(8)" ];
155 wantedBy = [ "multi-user.target" ];
158 ExecStart = "${pkgs.rasdaemon}/bin/ras-mc-ctl --register-labels";
159 RemainAfterExit = true;
165 meta.maintainers = [ lib.maintainers.evils ];