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