1{ config, lib, ... }:
2let
3
4 cfg = config.systemd.oomd;
5
6in
7{
8 imports = [
9 (lib.mkRenamedOptionModule
10 [ "systemd" "oomd" "enableUserServices" ]
11 [ "systemd" "oomd" "enableUserSlices" ]
12 )
13 ];
14
15 options.systemd.oomd = {
16 enable = lib.mkEnableOption "the `systemd-oomd` OOM killer" // {
17 default = true;
18 };
19
20 # Fedora enables the first and third option by default. See the 10-oomd-* files here:
21 # https://src.fedoraproject.org/rpms/systemd/tree/806c95e1c70af18f81d499b24cd7acfa4c36ffd6
22 enableRootSlice = lib.mkEnableOption "oomd on the root slice (`-.slice`)";
23 enableSystemSlice = lib.mkEnableOption "oomd on the system slice (`system.slice`)";
24 enableUserSlices = lib.mkEnableOption "oomd on all user slices (`user@.slice`) and all user owned slices";
25
26 extraConfig = lib.mkOption {
27 type =
28 with lib.types;
29 attrsOf (oneOf [
30 str
31 int
32 bool
33 ]);
34 default = { };
35 example = lib.literalExpression ''{ DefaultMemoryPressureDurationSec = "20s"; }'';
36 description = ''
37 Extra config options for `systemd-oomd`. See {command}`man oomd.conf`
38 for available options.
39 '';
40 };
41 };
42
43 config = lib.mkIf cfg.enable {
44 systemd.additionalUpstreamSystemUnits = [
45 "systemd-oomd.service"
46 "systemd-oomd.socket"
47 ];
48
49 systemd.services.systemd-oomd.after = [
50 "swap.target" # TODO: drop after systemd v258
51 "systemd-sysusers.service" # TODO: drop after systemd v257.8
52 ];
53 systemd.services.systemd-oomd.wantedBy = [ "multi-user.target" ];
54
55 environment.etc."systemd/oomd.conf".text = lib.generators.toINI { } {
56 OOM = cfg.extraConfig;
57 };
58
59 systemd.oomd.extraConfig.DefaultMemoryPressureDurationSec = lib.mkDefault "20s"; # Fedora default
60
61 users.users.systemd-oom = {
62 description = "systemd-oomd service user";
63 group = "systemd-oom";
64 isSystemUser = true;
65 };
66 users.groups.systemd-oom = { };
67
68 systemd.slices."-".sliceConfig = lib.mkIf cfg.enableRootSlice {
69 ManagedOOMMemoryPressure = "kill";
70 ManagedOOMMemoryPressureLimit = lib.mkDefault "80%";
71 };
72 systemd.slices."system".sliceConfig = lib.mkIf cfg.enableSystemSlice {
73 ManagedOOMMemoryPressure = "kill";
74 ManagedOOMMemoryPressureLimit = lib.mkDefault "80%";
75 };
76 systemd.slices."user".sliceConfig = lib.mkIf cfg.enableUserSlices {
77 ManagedOOMMemoryPressure = "kill";
78 ManagedOOMMemoryPressureLimit = lib.mkDefault "80%";
79 };
80 systemd.user.units."slice" = lib.mkIf cfg.enableUserSlices {
81 text = ''
82 [Slice]
83 ManagedOOMMemoryPressure=kill
84 ManagedOOMMemoryPressureLimit=80%
85 '';
86 overrideStrategy = "asDropin";
87 };
88 };
89}