at 23.11-pre 5.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 cfg = config.services.earlyoom; 5 6 inherit (lib) 7 mkDefault mkEnableOption mkIf mkOption types 8 mkRemovedOptionModule literalExpression 9 escapeShellArg concatStringsSep optional optionalString; 10 11in 12{ 13 options.services.earlyoom = { 14 enable = mkEnableOption (lib.mdDoc "Early out of memory killing"); 15 16 freeMemThreshold = mkOption { 17 type = types.ints.between 1 100; 18 default = 10; 19 description = lib.mdDoc '' 20 Minimum available memory (in percent). 21 22 If the available memory falls below this threshold (and the analog is true for 23 {option}`freeSwapThreshold`) the killing begins. 24 SIGTERM is sent first to the process that uses the most memory; then, if the available 25 memory falls below {option}`freeMemKillThreshold` (and the analog is true for 26 {option}`freeSwapKillThreshold`), SIGKILL is sent. 27 28 See [README](https://github.com/rfjakob/earlyoom#command-line-options) for details. 29 ''; 30 }; 31 32 freeMemKillThreshold = mkOption { 33 type = types.nullOr (types.ints.between 1 100); 34 default = null; 35 description = lib.mdDoc '' 36 Minimum available memory (in percent) before sending SIGKILL. 37 If unset, this defaults to half of {option}`freeMemThreshold`. 38 39 See the description of [](#opt-services.earlyoom.freeMemThreshold). 40 ''; 41 }; 42 43 freeSwapThreshold = mkOption { 44 type = types.ints.between 1 100; 45 default = 10; 46 description = lib.mdDoc '' 47 Minimum free swap space (in percent) before sending SIGTERM. 48 49 See the description of [](#opt-services.earlyoom.freeMemThreshold). 50 ''; 51 }; 52 53 freeSwapKillThreshold = mkOption { 54 type = types.nullOr (types.ints.between 1 100); 55 default = null; 56 description = lib.mdDoc '' 57 Minimum free swap space (in percent) before sending SIGKILL. 58 If unset, this defaults to half of {option}`freeSwapThreshold`. 59 60 See the description of [](#opt-services.earlyoom.freeMemThreshold). 61 ''; 62 }; 63 64 enableDebugInfo = mkOption { 65 type = types.bool; 66 default = false; 67 description = lib.mdDoc '' 68 Enable debugging messages. 69 ''; 70 }; 71 72 enableNotifications = mkOption { 73 type = types.bool; 74 default = false; 75 description = lib.mdDoc '' 76 Send notifications about killed processes via the system d-bus. 77 78 WARNING: enabling this option (while convenient) should *not* be done on a 79 machine where you do not trust the other users as it allows any other 80 local user to DoS your session by spamming notifications. 81 82 To actually see the notifications in your GUI session, you need to have 83 `systembus-notify` running as your user, which this 84 option handles by enabling {option}`services.systembus-notify`. 85 86 See [README](https://github.com/rfjakob/earlyoom#notifications) for details. 87 ''; 88 }; 89 90 killHook = mkOption { 91 type = types.nullOr types.path; 92 default = null; 93 example = literalExpression '' 94 pkgs.writeShellScript "earlyoom-kill-hook" ''' 95 echo "Process $EARLYOOM_NAME ($EARLYOOM_PID) was killed" >> /path/to/log 96 ''' 97 ''; 98 description = lib.mdDoc '' 99 An absolute path to an executable to be run for each process killed. 100 Some environment variables are available, see 101 [README](https://github.com/rfjakob/earlyoom#notifications) and 102 [the man page](https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#-n-pathtoscript) 103 for details. 104 ''; 105 }; 106 107 reportInterval = mkOption { 108 type = types.int; 109 default = 3600; 110 example = 0; 111 description = lib.mdDoc "Interval (in seconds) at which a memory report is printed (set to 0 to disable)."; 112 }; 113 114 extraArgs = mkOption { 115 type = types.listOf types.str; 116 default = []; 117 example = [ "-g" "--prefer '(^|/)(java|chromium)$'" ]; 118 description = lib.mdDoc "Extra command-line arguments to be passed to earlyoom."; 119 }; 120 }; 121 122 imports = [ 123 (mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] '' 124 This option is deprecated and ignored by earlyoom since 1.2. 125 '') 126 (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] '' 127 This option was removed in earlyoom 1.6, but was reimplemented in 1.7 128 and is available as the new option `services.earlyoom.killHook`. 129 '') 130 (mkRemovedOptionModule [ "services" "earlyoom" "ignoreOOMScoreAdjust" ] '' 131 This option is deprecated and ignored by earlyoom since 1.7. 132 '') 133 ]; 134 135 config = mkIf cfg.enable { 136 services.systembus-notify.enable = mkDefault cfg.enableNotifications; 137 138 systemd.services.earlyoom = { 139 description = "Early OOM Daemon for Linux"; 140 wantedBy = [ "multi-user.target" ]; 141 path = optional cfg.enableNotifications pkgs.dbus; 142 serviceConfig = { 143 StandardError = "journal"; 144 ExecStart = concatStringsSep " " ([ 145 "${pkgs.earlyoom}/bin/earlyoom" 146 ("-m ${toString cfg.freeMemThreshold}" 147 + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}") 148 ("-s ${toString cfg.freeSwapThreshold}" 149 + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}") 150 "-r ${toString cfg.reportInterval}" 151 ] 152 ++ optional cfg.enableDebugInfo "-d" 153 ++ optional cfg.enableNotifications "-n" 154 ++ optional (cfg.killHook != null) "-N ${escapeShellArg cfg.killHook}" 155 ++ cfg.extraArgs 156 ); 157 }; 158 }; 159 }; 160}