at 24.11-pre 24 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3with utils; 4with systemdUtils.unitOptions; 5with lib; 6 7let 8 9 cfg = config.systemd; 10 11 inherit (systemdUtils.lib) 12 generateUnits 13 targetToUnit 14 serviceToUnit 15 socketToUnit 16 timerToUnit 17 pathToUnit 18 mountToUnit 19 automountToUnit 20 sliceToUnit; 21 22 upstreamSystemUnits = 23 [ # Targets. 24 "basic.target" 25 "sysinit.target" 26 "sockets.target" 27 "exit.target" 28 "graphical.target" 29 "multi-user.target" 30 "network.target" 31 "network-pre.target" 32 "network-online.target" 33 "nss-lookup.target" 34 "nss-user-lookup.target" 35 "time-sync.target" 36 ] ++ optionals cfg.package.withCryptsetup [ 37 "cryptsetup.target" 38 "cryptsetup-pre.target" 39 "remote-cryptsetup.target" 40 ] ++ [ 41 "sigpwr.target" 42 "timers.target" 43 "paths.target" 44 "rpcbind.target" 45 46 # Rescue mode. 47 "rescue.target" 48 "rescue.service" 49 50 # systemd-debug-generator 51 "debug-shell.service" 52 53 # Udev. 54 "systemd-tmpfiles-setup-dev-early.service" 55 "systemd-udevd-control.socket" 56 "systemd-udevd-kernel.socket" 57 "systemd-udevd.service" 58 "systemd-udev-settle.service" 59 ] ++ (optional (!config.boot.isContainer) "systemd-udev-trigger.service") ++ [ 60 # hwdb.bin is managed by NixOS 61 # "systemd-hwdb-update.service" 62 63 # Consoles. 64 "getty.target" 65 "getty-pre.target" 66 "getty@.service" 67 "serial-getty@.service" 68 "console-getty.service" 69 "container-getty@.service" 70 "systemd-vconsole-setup.service" 71 72 # Hardware (started by udev when a relevant device is plugged in). 73 "sound.target" 74 "bluetooth.target" 75 "printer.target" 76 "smartcard.target" 77 78 # Kernel module loading. 79 "systemd-modules-load.service" 80 "kmod-static-nodes.service" 81 "modprobe@.service" 82 83 # Filesystems. 84 "systemd-fsck@.service" 85 "systemd-fsck-root.service" 86 "systemd-growfs@.service" 87 "systemd-growfs-root.service" 88 "systemd-remount-fs.service" 89 "systemd-pstore.service" 90 "local-fs.target" 91 "local-fs-pre.target" 92 "remote-fs.target" 93 "remote-fs-pre.target" 94 "swap.target" 95 "dev-hugepages.mount" 96 "dev-mqueue.mount" 97 "sys-fs-fuse-connections.mount" 98 ] ++ (optional (!config.boot.isContainer) "sys-kernel-config.mount") ++ [ 99 "sys-kernel-debug.mount" 100 101 # Maintaining state across reboots. 102 "systemd-random-seed.service" 103 ] ++ (optional cfg.package.withBootloader "systemd-boot-random-seed.service") ++ [ 104 "systemd-backlight@.service" 105 "systemd-rfkill.service" 106 "systemd-rfkill.socket" 107 108 # Hibernate / suspend. 109 "hibernate.target" 110 "suspend.target" 111 "suspend-then-hibernate.target" 112 "sleep.target" 113 "hybrid-sleep.target" 114 "systemd-hibernate.service" 115 "systemd-hybrid-sleep.service" 116 "systemd-suspend.service" 117 "systemd-suspend-then-hibernate.service" 118 119 # Reboot stuff. 120 "reboot.target" 121 "systemd-reboot.service" 122 "poweroff.target" 123 "systemd-poweroff.service" 124 "halt.target" 125 "systemd-halt.service" 126 "shutdown.target" 127 "umount.target" 128 "final.target" 129 "kexec.target" 130 "systemd-kexec.service" 131 ] ++ lib.optional cfg.package.withUtmp "systemd-update-utmp.service" ++ [ 132 133 # Password entry. 134 "systemd-ask-password-console.path" 135 "systemd-ask-password-console.service" 136 "systemd-ask-password-wall.path" 137 "systemd-ask-password-wall.service" 138 139 # Slices / containers. 140 "slices.target" 141 ] ++ optionals cfg.package.withImportd [ 142 "systemd-importd.service" 143 ] ++ optionals cfg.package.withMachined [ 144 "machine.slice" 145 "machines.target" 146 "systemd-machined.service" 147 ] ++ [ 148 "systemd-nspawn@.service" 149 150 # Misc. 151 "systemd-sysctl.service" 152 ] ++ optionals cfg.package.withTimedated [ 153 "dbus-org.freedesktop.timedate1.service" 154 "systemd-timedated.service" 155 ] ++ optionals cfg.package.withLocaled [ 156 "dbus-org.freedesktop.locale1.service" 157 "systemd-localed.service" 158 ] ++ optionals cfg.package.withHostnamed [ 159 "dbus-org.freedesktop.hostname1.service" 160 "systemd-hostnamed.service" 161 ] ++ optionals cfg.package.withPortabled [ 162 "dbus-org.freedesktop.portable1.service" 163 "systemd-portabled.service" 164 ] ++ [ 165 "systemd-exit.service" 166 "systemd-update-done.service" 167 ] ++ cfg.additionalUpstreamSystemUnits; 168 169 upstreamSystemWants = 170 [ "sysinit.target.wants" 171 "sockets.target.wants" 172 "local-fs.target.wants" 173 "multi-user.target.wants" 174 "timers.target.wants" 175 ]; 176 177 proxy_env = config.networking.proxy.envVars; 178 179in 180 181{ 182 ###### interface 183 184 options.systemd = { 185 186 package = mkPackageOption pkgs "systemd" {}; 187 188 units = mkOption { 189 description = "Definition of systemd units; see {manpage}`systemd.unit(5)`."; 190 default = {}; 191 type = systemdUtils.types.units; 192 }; 193 194 packages = mkOption { 195 default = []; 196 type = types.listOf types.package; 197 example = literalExpression "[ pkgs.systemd-cryptsetup-generator ]"; 198 description = "Packages providing systemd units and hooks."; 199 }; 200 201 targets = mkOption { 202 default = {}; 203 type = systemdUtils.types.targets; 204 description = "Definition of systemd target units; see {manpage}`systemd.target(5)`"; 205 }; 206 207 services = mkOption { 208 default = {}; 209 type = systemdUtils.types.services; 210 description = "Definition of systemd service units; see {manpage}`systemd.service(5)`."; 211 }; 212 213 sockets = mkOption { 214 default = {}; 215 type = systemdUtils.types.sockets; 216 description = "Definition of systemd socket units; see {manpage}`systemd.socket(5)`."; 217 }; 218 219 timers = mkOption { 220 default = {}; 221 type = systemdUtils.types.timers; 222 description = "Definition of systemd timer units; see {manpage}`systemd.timer(5)`."; 223 }; 224 225 paths = mkOption { 226 default = {}; 227 type = systemdUtils.types.paths; 228 description = "Definition of systemd path units; see {manpage}`systemd.path(5)`."; 229 }; 230 231 mounts = mkOption { 232 default = []; 233 type = systemdUtils.types.mounts; 234 description = '' 235 Definition of systemd mount units; see {manpage}`systemd.mount(5)`. 236 237 This is a list instead of an attrSet, because systemd mandates 238 the names to be derived from the `where` attribute. 239 ''; 240 }; 241 242 automounts = mkOption { 243 default = []; 244 type = systemdUtils.types.automounts; 245 description = '' 246 Definition of systemd automount units; see {manpage}`systemd.automount(5)`. 247 248 This is a list instead of an attrSet, because systemd mandates 249 the names to be derived from the `where` attribute. 250 ''; 251 }; 252 253 slices = mkOption { 254 default = {}; 255 type = systemdUtils.types.slices; 256 description = "Definition of slice configurations; see {manpage}`systemd.slice(5)`."; 257 }; 258 259 generators = mkOption { 260 type = types.attrsOf types.path; 261 default = {}; 262 example = { systemd-gpt-auto-generator = "/dev/null"; }; 263 description = '' 264 Definition of systemd generators; see {manpage}`systemd.generator(5)`. 265 266 For each `NAME = VALUE` pair of the attrSet, a link is generated from 267 `/etc/systemd/system-generators/NAME` to `VALUE`. 268 ''; 269 }; 270 271 shutdown = mkOption { 272 type = types.attrsOf types.path; 273 default = {}; 274 description = '' 275 Definition of systemd shutdown executables. 276 For each `NAME = VALUE` pair of the attrSet, a link is generated from 277 `/etc/systemd/system-shutdown/NAME` to `VALUE`. 278 ''; 279 }; 280 281 defaultUnit = mkOption { 282 default = "multi-user.target"; 283 type = types.str; 284 description = '' 285 Default unit started when the system boots; see {manpage}`systemd.special(7)`. 286 ''; 287 }; 288 289 ctrlAltDelUnit = mkOption { 290 default = "reboot.target"; 291 type = types.str; 292 example = "poweroff.target"; 293 description = '' 294 Target that should be started when Ctrl-Alt-Delete is pressed; 295 see {manpage}`systemd.special(7)`. 296 ''; 297 }; 298 299 globalEnvironment = mkOption { 300 type = with types; attrsOf (nullOr (oneOf [ str path package ])); 301 default = {}; 302 example = { TZ = "CET"; }; 303 description = '' 304 Environment variables passed to *all* systemd units. 305 ''; 306 }; 307 308 managerEnvironment = mkOption { 309 type = with types; attrsOf (nullOr (oneOf [ str path package ])); 310 default = {}; 311 example = { SYSTEMD_LOG_LEVEL = "debug"; }; 312 description = '' 313 Environment variables of PID 1. These variables are 314 *not* passed to started units. 315 ''; 316 }; 317 318 enableCgroupAccounting = mkOption { 319 default = true; 320 type = types.bool; 321 description = '' 322 Whether to enable cgroup accounting; see {manpage}`cgroups(7)`. 323 ''; 324 }; 325 326 enableUnifiedCgroupHierarchy = mkOption { 327 default = true; 328 type = types.bool; 329 description = '' 330 Whether to enable the unified cgroup hierarchy (cgroupsv2); see {manpage}`cgroups(7)`. 331 ''; 332 }; 333 334 extraConfig = mkOption { 335 default = ""; 336 type = types.lines; 337 example = "DefaultLimitCORE=infinity"; 338 description = '' 339 Extra config options for systemd. See {manpage}`systemd-system.conf(5)` man page 340 for available options. 341 ''; 342 }; 343 344 sleep.extraConfig = mkOption { 345 default = ""; 346 type = types.lines; 347 example = "HibernateDelaySec=1h"; 348 description = '' 349 Extra config options for systemd sleep state logic. 350 See {manpage}`sleep.conf.d(5)` man page for available options. 351 ''; 352 }; 353 354 additionalUpstreamSystemUnits = mkOption { 355 default = [ ]; 356 type = types.listOf types.str; 357 example = [ "debug-shell.service" "systemd-quotacheck.service" ]; 358 description = '' 359 Additional units shipped with systemd that shall be enabled. 360 ''; 361 }; 362 363 suppressedSystemUnits = mkOption { 364 default = [ ]; 365 type = types.listOf types.str; 366 example = [ "systemd-backlight@.service" ]; 367 description = '' 368 A list of units to skip when generating system systemd configuration directory. This has 369 priority over upstream units, {option}`systemd.units`, and 370 {option}`systemd.additionalUpstreamSystemUnits`. The main purpose of this is to 371 prevent a upstream systemd unit from being added to the initrd with any modifications made to it 372 by other NixOS modules. 373 ''; 374 }; 375 376 watchdog.device = mkOption { 377 type = types.nullOr types.path; 378 default = null; 379 example = "/dev/watchdog"; 380 description = '' 381 The path to a hardware watchdog device which will be managed by systemd. 382 If not specified, systemd will default to `/dev/watchdog`. 383 ''; 384 }; 385 386 watchdog.runtimeTime = mkOption { 387 type = types.nullOr types.str; 388 default = null; 389 example = "30s"; 390 description = '' 391 The amount of time which can elapse before a watchdog hardware device 392 will automatically reboot the system. 393 394 Valid time units include "ms", "s", "min", "h", "d", and "w"; 395 see {manpage}`systemd.time(7)`. 396 ''; 397 }; 398 399 watchdog.rebootTime = mkOption { 400 type = types.nullOr types.str; 401 default = null; 402 example = "10m"; 403 description = '' 404 The amount of time which can elapse after a reboot has been triggered 405 before a watchdog hardware device will automatically reboot the system. 406 If left `null`, systemd will use its default of 10 minutes; 407 see {manpage}`systemd-system.conf(5)`. 408 409 Valid time units include "ms", "s", "min", "h", "d", and "w"; 410 see also {manpage}`systemd.time(7)`. 411 ''; 412 }; 413 414 watchdog.kexecTime = mkOption { 415 type = types.nullOr types.str; 416 default = null; 417 example = "10m"; 418 description = '' 419 The amount of time which can elapse when `kexec` is being executed before 420 a watchdog hardware device will automatically reboot the system. This 421 option should only be enabled if `reloadTime` is also enabled; 422 see {manpage}`kexec(8)`. 423 424 Valid time units include "ms", "s", "min", "h", "d", and "w"; 425 see also {manpage}`systemd.time(7)`. 426 ''; 427 }; 428 }; 429 430 431 ###### implementation 432 433 config = { 434 435 warnings = let 436 mkOneNetOnlineWarn = typeStr: name: def: lib.optional 437 (lib.elem "network-online.target" def.after && !(lib.elem "network-online.target" (def.wants ++ def.requires ++ def.bindsTo))) 438 "${name}.${typeStr} is ordered after 'network-online.target' but doesn't depend on it"; 439 mkNetOnlineWarns = typeStr: defs: lib.concatLists (lib.mapAttrsToList (mkOneNetOnlineWarn typeStr) defs); 440 mkMountNetOnlineWarns = typeStr: defs: lib.concatLists (map (m: mkOneNetOnlineWarn typeStr m.what m) defs); 441 in concatLists ( 442 mapAttrsToList 443 (name: service: 444 let 445 type = service.serviceConfig.Type or ""; 446 restart = service.serviceConfig.Restart or "no"; 447 hasDeprecated = builtins.hasAttr "StartLimitInterval" service.serviceConfig; 448 in 449 concatLists [ 450 (optional (type == "oneshot" && (restart == "always" || restart == "on-success")) 451 "Service '${name}.service' with 'Type=oneshot' cannot have 'Restart=always' or 'Restart=on-success'" 452 ) 453 (optional hasDeprecated 454 "Service '${name}.service' uses the attribute 'StartLimitInterval' in the Service section, which is deprecated. See https://github.com/NixOS/nixpkgs/issues/45786." 455 ) 456 (optional (service.reloadIfChanged && service.reloadTriggers != []) 457 "Service '${name}.service' has both 'reloadIfChanged' and 'reloadTriggers' set. This is probably not what you want, because 'reloadTriggers' behave the same whay as 'restartTriggers' if 'reloadIfChanged' is set." 458 ) 459 ] 460 ) 461 cfg.services 462 ) 463 ++ (mkNetOnlineWarns "target" cfg.targets) 464 ++ (mkNetOnlineWarns "service" cfg.services) 465 ++ (mkNetOnlineWarns "socket" cfg.sockets) 466 ++ (mkNetOnlineWarns "timer" cfg.timers) 467 ++ (mkNetOnlineWarns "path" cfg.paths) 468 ++ (mkMountNetOnlineWarns "mount" cfg.mounts) 469 ++ (mkMountNetOnlineWarns "automount" cfg.automounts) 470 ++ (mkNetOnlineWarns "slice" cfg.slices); 471 472 assertions = concatLists ( 473 mapAttrsToList 474 (name: service: 475 map (message: { 476 assertion = false; 477 inherit message; 478 }) (concatLists [ 479 (optional ((builtins.elem "network-interfaces.target" service.after) || (builtins.elem "network-interfaces.target" service.wants)) 480 "Service '${name}.service' is using the deprecated target network-interfaces.target, which no longer exists. Using network.target is recommended instead." 481 ) 482 ]) 483 ) 484 cfg.services 485 ); 486 487 system.build.units = cfg.units; 488 489 system.nssModules = [ cfg.package.out ]; 490 system.nssDatabases = { 491 hosts = (mkMerge [ 492 (mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is mkBefore'd) 493 (mkOrder 999 ["myhostname"]) # after files (which is 998), but before regular nss modules 494 ]); 495 passwd = (mkMerge [ 496 (mkAfter [ "systemd" ]) 497 ]); 498 group = (mkMerge [ 499 (mkAfter [ "[success=merge] systemd" ]) # need merge so that NSS won't stop at file-based groups 500 ]); 501 }; 502 503 environment.systemPackages = [ cfg.package ]; 504 505 environment.etc = let 506 # generate contents for /etc/systemd/system-${type} from attrset of links and packages 507 hooks = type: links: pkgs.runCommand "system-${type}" { 508 preferLocalBuild = true; 509 packages = cfg.packages; 510 } '' 511 set -e 512 mkdir -p $out 513 for package in $packages 514 do 515 for hook in $package/lib/systemd/system-${type}/* 516 do 517 ln -s $hook $out/ 518 done 519 done 520 ${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)} 521 ''; 522 523 enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits; 524 enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units; 525 526 in ({ 527 "systemd/system".source = generateUnits { 528 type = "system"; 529 units = enabledUnits; 530 upstreamUnits = enabledUpstreamSystemUnits; 531 upstreamWants = upstreamSystemWants; 532 }; 533 534 "systemd/system.conf".text = '' 535 [Manager] 536 ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)} 537 ${optionalString cfg.enableCgroupAccounting '' 538 DefaultCPUAccounting=yes 539 DefaultIOAccounting=yes 540 DefaultBlockIOAccounting=yes 541 DefaultIPAccounting=yes 542 ''} 543 DefaultLimitCORE=infinity 544 ${optionalString (cfg.watchdog.device != null) '' 545 WatchdogDevice=${cfg.watchdog.device} 546 ''} 547 ${optionalString (cfg.watchdog.runtimeTime != null) '' 548 RuntimeWatchdogSec=${cfg.watchdog.runtimeTime} 549 ''} 550 ${optionalString (cfg.watchdog.rebootTime != null) '' 551 RebootWatchdogSec=${cfg.watchdog.rebootTime} 552 ''} 553 ${optionalString (cfg.watchdog.kexecTime != null) '' 554 KExecWatchdogSec=${cfg.watchdog.kexecTime} 555 ''} 556 557 ${cfg.extraConfig} 558 ''; 559 560 "systemd/sleep.conf".text = '' 561 [Sleep] 562 ${cfg.sleep.extraConfig} 563 ''; 564 565 "systemd/system-generators" = { source = hooks "generators" cfg.generators; }; 566 "systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; }; 567 }); 568 569 services.dbus.enable = true; 570 571 users.users.systemd-network = { 572 uid = config.ids.uids.systemd-network; 573 group = "systemd-network"; 574 }; 575 users.groups.systemd-network.gid = config.ids.gids.systemd-network; 576 users.users.systemd-resolve = { 577 uid = config.ids.uids.systemd-resolve; 578 group = "systemd-resolve"; 579 }; 580 users.groups.systemd-resolve.gid = config.ids.gids.systemd-resolve; 581 582 # Target for ‘charon send-keys’ to hook into. 583 users.groups.keys.gid = config.ids.gids.keys; 584 585 systemd.targets.keys = 586 { description = "Security Keys"; 587 unitConfig.X-StopOnReconfiguration = true; 588 }; 589 590 # This target only exists so that services ordered before sysinit.target 591 # are restarted in the correct order, notably BEFORE the other services, 592 # when switching configurations. 593 systemd.targets.sysinit-reactivation = { 594 description = "Reactivate sysinit units"; 595 }; 596 597 systemd.units = 598 let 599 withName = cfgToUnit: cfg: lib.nameValuePair cfg.name (cfgToUnit cfg); 600 in 601 mapAttrs' (_: withName pathToUnit) cfg.paths 602 // mapAttrs' (_: withName serviceToUnit) cfg.services 603 // mapAttrs' (_: withName sliceToUnit) cfg.slices 604 // mapAttrs' (_: withName socketToUnit) cfg.sockets 605 // mapAttrs' (_: withName targetToUnit) cfg.targets 606 // mapAttrs' (_: withName timerToUnit) cfg.timers 607 // listToAttrs (map (withName mountToUnit) cfg.mounts) 608 // listToAttrs (map (withName automountToUnit) cfg.automounts); 609 610 # Environment of PID 1 611 systemd.managerEnvironment = { 612 # Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools 613 # util-linux is needed for the main fsck utility wrapping the fs-specific ones 614 PATH = lib.makeBinPath (config.system.fsPackages ++ [cfg.package.util-linux]); 615 LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; 616 TZDIR = "/etc/zoneinfo"; 617 # If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable 618 SYSTEMD_UNIT_PATH = lib.mkIf (config.boot.extraSystemdUnitPaths != []) "${builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths}:"; 619 }; 620 621 622 system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled 623 [ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET" 624 "SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC" 625 "CRYPTO_SHA256" "DMIID" "AUTOFS_FS" "TMPFS_POSIX_ACL" 626 "TMPFS_XATTR" "SECCOMP" 627 ]; 628 629 # Generate timer units for all services that have a ‘startAt’ value. 630 systemd.timers = 631 mapAttrs (name: service: 632 { wantedBy = [ "timers.target" ]; 633 timerConfig.OnCalendar = service.startAt; 634 }) 635 (filterAttrs (name: service: service.enable && service.startAt != []) cfg.services); 636 637 # Some overrides to upstream units. 638 systemd.services."systemd-backlight@".restartIfChanged = false; 639 systemd.services."systemd-fsck@".restartIfChanged = false; 640 systemd.services."systemd-fsck@".path = [ pkgs.util-linux ] ++ config.system.fsPackages; 641 systemd.services."systemd-makefs@" = { 642 restartIfChanged = false; 643 path = [ pkgs.util-linux ] ++ config.system.fsPackages; 644 # Since there is no /etc/systemd/system/systemd-makefs@.service 645 # file, the units generated in /run/systemd/generator would 646 # override anything we put here. But by forcing the use of a 647 # drop-in in /etc, it does apply. 648 overrideStrategy = "asDropin"; 649 }; 650 systemd.services."systemd-mkswap@" = { 651 restartIfChanged = false; 652 path = [ pkgs.util-linux ]; 653 overrideStrategy = "asDropin"; 654 }; 655 systemd.services.systemd-random-seed.restartIfChanged = false; 656 systemd.services.systemd-remount-fs.restartIfChanged = false; 657 systemd.services.systemd-update-utmp.restartIfChanged = false; 658 systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild 659 systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true; 660 systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true; 661 systemd.targets.network-online.wantedBy = [ "multi-user.target" ]; 662 systemd.services.systemd-importd.environment = proxy_env; 663 systemd.services.systemd-pstore.wantedBy = [ "sysinit.target" ]; # see #81138 664 665 # NixOS has kernel modules in a different location, so override that here. 666 systemd.services.kmod-static-nodes.unitConfig.ConditionFileNotEmpty = [ 667 "" # required to unset the previous value! 668 "/run/booted-system/kernel-modules/lib/modules/%v/modules.devname" 669 ]; 670 671 # Don't bother with certain units in containers. 672 systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container"; 673 674 # Increase numeric PID range (set directly instead of copying a one-line file from systemd) 675 # https://github.com/systemd/systemd/pull/12226 676 boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.is64bit (lib.mkDefault 4194304); 677 678 boot.kernelParams = optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0"; 679 680 # Avoid potentially degraded system state due to 681 # "Userspace Out-Of-Memory (OOM) Killer was skipped because of a failed condition check (ConditionControlGroupController=v2)." 682 systemd.oomd.enable = mkIf (!cfg.enableUnifiedCgroupHierarchy) false; 683 684 services.logrotate.settings = { 685 "/var/log/btmp" = mapAttrs (_: mkDefault) { 686 frequency = "monthly"; 687 rotate = 1; 688 create = "0660 root ${config.users.groups.utmp.name}"; 689 minsize = "1M"; 690 }; 691 "/var/log/wtmp" = mapAttrs (_: mkDefault) { 692 frequency = "monthly"; 693 rotate = 1; 694 create = "0664 root ${config.users.groups.utmp.name}"; 695 minsize = "1M"; 696 }; 697 }; 698 }; 699 700 # FIXME: Remove these eventually. 701 imports = 702 [ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ]) 703 (mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ]) 704 (mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ]) 705 (mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ]) 706 (mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.") 707 ]; 708}