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