at 23.11-pre 4.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.hardware.rasdaemon; 8 9in 10{ 11 options.hardware.rasdaemon = { 12 13 enable = mkEnableOption (lib.mdDoc "RAS logging daemon"); 14 15 record = mkOption { 16 type = types.bool; 17 default = true; 18 description = lib.mdDoc "record events via sqlite3, required for ras-mc-ctl"; 19 }; 20 21 mainboard = mkOption { 22 type = types.lines; 23 default = ""; 24 description = lib.mdDoc "Custom mainboard description, see {manpage}`ras-mc-ctl(8)` for more details."; 25 example = '' 26 vendor = ASRock 27 model = B450M Pro4 28 29 # it should default to such values from 30 # /sys/class/dmi/id/board_[vendor|name] 31 # alternatively one can supply a script 32 # that returns the same format as above 33 34 script = <path to script> 35 ''; 36 }; 37 38 # TODO, accept `rasdaemon.labels = " ";` or `rasdaemon.labels = { dell = " "; asrock = " "; };' 39 40 labels = mkOption { 41 type = types.lines; 42 default = ""; 43 description = lib.mdDoc "Additional memory module label descriptions to be placed in /etc/ras/dimm_labels.d/labels"; 44 example = '' 45 # vendor and model may be shown by 'ras-mc-ctl --mainboard' 46 vendor: ASRock 47 product: To Be Filled By O.E.M. 48 model: B450M Pro4 49 # these labels are names for the motherboard slots 50 # the numbers may be shown by `ras-mc-ctl --error-count` 51 # they are mc:csrow:channel 52 DDR4_A1: 0.2.0; DDR4_B1: 0.2.1; 53 DDR4_A2: 0.3.0; DDR4_B2: 0.3.1; 54 ''; 55 }; 56 57 config = mkOption { 58 type = types.lines; 59 default = ""; 60 description = lib.mdDoc '' 61 rasdaemon configuration, currently only used for CE PFA 62 for details, read rasdaemon.outPath/etc/sysconfig/rasdaemon's comments 63 ''; 64 example = '' 65 # defaults from included config 66 PAGE_CE_REFRESH_CYCLE="24h" 67 PAGE_CE_THRESHOLD="50" 68 PAGE_CE_ACTION="soft" 69 ''; 70 }; 71 72 extraModules = mkOption { 73 type = types.listOf types.str; 74 default = []; 75 description = lib.mdDoc "extra kernel modules to load"; 76 example = [ "i7core_edac" ]; 77 }; 78 79 testing = mkEnableOption (lib.mdDoc "error injection infrastructure"); 80 }; 81 82 config = mkIf cfg.enable { 83 84 environment.etc = { 85 "ras/mainboard" = { 86 enable = cfg.mainboard != ""; 87 text = cfg.mainboard; 88 }; 89 # TODO, handle multiple cfg.labels.brand = " "; 90 "ras/dimm_labels.d/labels" = { 91 enable = cfg.labels != ""; 92 text = cfg.labels; 93 }; 94 "sysconfig/rasdaemon" = { 95 enable = cfg.config != ""; 96 text = cfg.config; 97 }; 98 }; 99 environment.systemPackages = [ pkgs.rasdaemon ] 100 ++ optionals (cfg.testing) (with pkgs.error-inject; [ 101 edac-inject 102 mce-inject 103 aer-inject 104 ]); 105 106 boot.initrd.kernelModules = cfg.extraModules 107 ++ optionals (cfg.testing) [ 108 # edac_core and amd64_edac should get loaded automatically 109 # i7core_edac may not be, and may not be required, but should load successfully 110 "edac_core" 111 "amd64_edac" 112 "i7core_edac" 113 "mce-inject" 114 "aer-inject" 115 ]; 116 117 boot.kernelPatches = optionals (cfg.testing) [{ 118 name = "rasdaemon-tests"; 119 patch = null; 120 extraConfig = '' 121 EDAC_DEBUG y 122 X86_MCE_INJECT y 123 124 PCIEPORTBUS y 125 PCIEAER y 126 PCIEAER_INJECT y 127 ''; 128 }]; 129 130 # i tried to set up a group for this 131 # but rasdaemon needs higher permissions? 132 # `rasdaemon: Can't locate a mounted debugfs` 133 134 # most of this taken from src/misc/ 135 systemd.services = { 136 rasdaemon = { 137 description = "the RAS logging daemon"; 138 documentation = [ "man:rasdaemon(1)" ]; 139 wantedBy = [ "multi-user.target" ]; 140 141 serviceConfig = { 142 StateDirectory = optionalString (cfg.record) "rasdaemon"; 143 144 ExecStart = "${pkgs.rasdaemon}/bin/rasdaemon --foreground" 145 + optionalString (cfg.record) " --record"; 146 ExecStop = "${pkgs.rasdaemon}/bin/rasdaemon --disable"; 147 Restart = "on-abort"; 148 149 # src/misc/rasdaemon.service.in shows this: 150 # ExecStartPost = ${pkgs.rasdaemon}/bin/rasdaemon --enable 151 # but that results in unpredictable existence of the database 152 # and everything seems to be enabled without this... 153 }; 154 }; 155 ras-mc-ctl = mkIf (cfg.labels != "") { 156 description = "register DIMM labels on startup"; 157 documentation = [ "man:ras-mc-ctl(8)" ]; 158 wantedBy = [ "multi-user.target" ]; 159 serviceConfig = { 160 Type = "oneshot"; 161 ExecStart = "${pkgs.rasdaemon}/bin/ras-mc-ctl --register-labels"; 162 RemainAfterExit = true; 163 }; 164 }; 165 }; 166 }; 167 168 meta.maintainers = [ maintainers.evils ]; 169 170}