at v206 25 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3with utils; 4with lib; 5with import ./systemd-unit-options.nix { inherit config lib; }; 6with import ./systemd-lib.nix { inherit config lib pkgs; }; 7 8let 9 10 cfg = config.systemd; 11 12 systemd = cfg.package; 13 14 upstreamSystemUnits = 15 [ # Targets. 16 "basic.target" 17 "sysinit.target" 18 "sockets.target" 19 "graphical.target" 20 "multi-user.target" 21 "network.target" 22 "network-pre.target" 23 "network-online.target" 24 "nss-lookup.target" 25 "nss-user-lookup.target" 26 "time-sync.target" 27 #"cryptsetup.target" 28 "sigpwr.target" 29 "timers.target" 30 "paths.target" 31 "rpcbind.target" 32 33 # Rescue mode. 34 "rescue.target" 35 "rescue.service" 36 37 # Udev. 38 "systemd-udevd-control.socket" 39 "systemd-udevd-kernel.socket" 40 "systemd-udevd.service" 41 "systemd-udev-settle.service" 42 "systemd-udev-trigger.service" 43 44 # Consoles. 45 "getty.target" 46 "getty@.service" 47 "serial-getty@.service" 48 "container-getty@.service" 49 "systemd-vconsole-setup.service" 50 51 # Hardware (started by udev when a relevant device is plugged in). 52 "sound.target" 53 "bluetooth.target" 54 "printer.target" 55 "smartcard.target" 56 57 # Login stuff. 58 "systemd-logind.service" 59 "autovt@.service" 60 #"systemd-vconsole-setup.service" 61 "systemd-user-sessions.service" 62 "dbus-org.freedesktop.login1.service" 63 "dbus-org.freedesktop.machine1.service" 64 "user@.service" 65 66 # Journal. 67 "systemd-journald.socket" 68 "systemd-journald.service" 69 "systemd-journal-flush.service" 70 "systemd-journal-gatewayd.socket" 71 "systemd-journal-gatewayd.service" 72 "systemd-journald-dev-log.socket" 73 "syslog.socket" 74 75 # SysV init compatibility. 76 "systemd-initctl.socket" 77 "systemd-initctl.service" 78 79 # Kernel module loading. 80 "systemd-modules-load.service" 81 "kmod-static-nodes.service" 82 83 # Filesystems. 84 "systemd-fsck@.service" 85 "systemd-fsck-root.service" 86 "systemd-remount-fs.service" 87 "local-fs.target" 88 "local-fs-pre.target" 89 "remote-fs.target" 90 "remote-fs-pre.target" 91 "swap.target" 92 "dev-hugepages.mount" 93 "dev-mqueue.mount" 94 "proc-sys-fs-binfmt_misc.mount" 95 "sys-fs-fuse-connections.mount" 96 "sys-kernel-config.mount" 97 "sys-kernel-debug.mount" 98 99 # Maintaining state across reboots. 100 "systemd-random-seed.service" 101 "systemd-backlight@.service" 102 "systemd-rfkill@.service" 103 104 # Hibernate / suspend. 105 "hibernate.target" 106 "suspend.target" 107 "sleep.target" 108 "hybrid-sleep.target" 109 "systemd-hibernate.service" 110 "systemd-suspend.service" 111 "systemd-hybrid-sleep.service" 112 "systemd-shutdownd.socket" 113 "systemd-shutdownd.service" 114 115 # Reboot stuff. 116 "reboot.target" 117 "systemd-reboot.service" 118 "poweroff.target" 119 "systemd-poweroff.service" 120 "halt.target" 121 "systemd-halt.service" 122 "ctrl-alt-del.target" 123 "shutdown.target" 124 "umount.target" 125 "final.target" 126 "kexec.target" 127 "systemd-kexec.service" 128 "systemd-update-utmp.service" 129 130 # Password entry. 131 "systemd-ask-password-console.path" 132 "systemd-ask-password-console.service" 133 "systemd-ask-password-wall.path" 134 "systemd-ask-password-wall.service" 135 136 # Slices / containers. 137 "slices.target" 138 "-.slice" 139 "system.slice" 140 "user.slice" 141 "machine.slice" 142 "systemd-machined.service" 143 144 # Temporary file creation / cleanup. 145 "systemd-tmpfiles-clean.service" 146 "systemd-tmpfiles-clean.timer" 147 "systemd-tmpfiles-setup.service" 148 "systemd-tmpfiles-setup-dev.service" 149 150 # Misc. 151 "systemd-sysctl.service" 152 ] 153 154 ++ cfg.additionalUpstreamSystemUnits; 155 156 upstreamSystemWants = 157 [ #"basic.target.wants" 158 "sysinit.target.wants" 159 "sockets.target.wants" 160 "local-fs.target.wants" 161 "multi-user.target.wants" 162 "timers.target.wants" 163 ]; 164 165 upstreamUserUnits = 166 [ "basic.target" 167 "default.target" 168 "exit.target" 169 "paths.target" 170 "shutdown.target" 171 "sockets.target" 172 "systemd-exit.service" 173 "timers.target" 174 ]; 175 176 makeJobScript = name: text: 177 let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${shellEscape name}"; inherit text; }; 178 in "${x}/bin/${shellEscape name}"; 179 180 unitConfig = { name, config, ... }: { 181 config = { 182 unitConfig = 183 optionalAttrs (config.requires != []) 184 { Requires = toString config.requires; } 185 // optionalAttrs (config.wants != []) 186 { Wants = toString config.wants; } 187 // optionalAttrs (config.after != []) 188 { After = toString config.after; } 189 // optionalAttrs (config.before != []) 190 { Before = toString config.before; } 191 // optionalAttrs (config.bindsTo != []) 192 { BindsTo = toString config.bindsTo; } 193 // optionalAttrs (config.partOf != []) 194 { PartOf = toString config.partOf; } 195 // optionalAttrs (config.conflicts != []) 196 { Conflicts = toString config.conflicts; } 197 // optionalAttrs (config.requisite != []) 198 { Requisite = toString config.requisite; } 199 // optionalAttrs (config.restartTriggers != []) 200 { X-Restart-Triggers = toString config.restartTriggers; } 201 // optionalAttrs (config.description != "") { 202 Description = config.description; 203 }; 204 }; 205 }; 206 207 serviceConfig = { name, config, ... }: { 208 config = mkMerge 209 [ { # Default path for systemd services. Should be quite minimal. 210 path = 211 [ pkgs.coreutils 212 pkgs.findutils 213 pkgs.gnugrep 214 pkgs.gnused 215 systemd 216 ]; 217 environment.PATH = config.path; 218 } 219 (mkIf (config.preStart != "") 220 { serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" '' 221 #! ${pkgs.stdenv.shell} -e 222 ${config.preStart} 223 ''; 224 }) 225 (mkIf (config.script != "") 226 { serviceConfig.ExecStart = makeJobScript "${name}-start" '' 227 #! ${pkgs.stdenv.shell} -e 228 ${config.script} 229 '' + " " + config.scriptArgs; 230 }) 231 (mkIf (config.postStart != "") 232 { serviceConfig.ExecStartPost = makeJobScript "${name}-post-start" '' 233 #! ${pkgs.stdenv.shell} -e 234 ${config.postStart} 235 ''; 236 }) 237 (mkIf (config.reload != "") 238 { serviceConfig.ExecReload = makeJobScript "${name}-reload" '' 239 #! ${pkgs.stdenv.shell} -e 240 ${config.reload} 241 ''; 242 }) 243 (mkIf (config.preStop != "") 244 { serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" '' 245 #! ${pkgs.stdenv.shell} -e 246 ${config.preStop} 247 ''; 248 }) 249 (mkIf (config.postStop != "") 250 { serviceConfig.ExecStopPost = makeJobScript "${name}-post-stop" '' 251 #! ${pkgs.stdenv.shell} -e 252 ${config.postStop} 253 ''; 254 }) 255 ]; 256 }; 257 258 mountConfig = { name, config, ... }: { 259 config = { 260 mountConfig = 261 { What = config.what; 262 Where = config.where; 263 } // optionalAttrs (config.type != "") { 264 Type = config.type; 265 } // optionalAttrs (config.options != "") { 266 Options = config.options; 267 }; 268 }; 269 }; 270 271 automountConfig = { name, config, ... }: { 272 config = { 273 automountConfig = 274 { Where = config.where; 275 }; 276 }; 277 }; 278 279 commonUnitText = def: '' 280 [Unit] 281 ${attrsToSection def.unitConfig} 282 ''; 283 284 targetToUnit = name: def: 285 { inherit (def) wantedBy requiredBy enable; 286 text = 287 '' 288 [Unit] 289 ${attrsToSection def.unitConfig} 290 ''; 291 }; 292 293 serviceToUnit = name: def: 294 { inherit (def) wantedBy requiredBy enable; 295 text = commonUnitText def + 296 '' 297 [Service] 298 ${let env = cfg.globalEnvironment // def.environment; 299 in concatMapStrings (n: 300 let s = optionalString (env."${n}" != null) 301 "Environment=\"${n}=${env.${n}}\"\n"; 302 in if stringLength s >= 2048 then throw "The value of the environment variable ${n} in systemd service ${name}.service is too long." else s) (attrNames env)} 303 ${if def.reloadIfChanged then '' 304 X-ReloadIfChanged=true 305 '' else if !def.restartIfChanged then '' 306 X-RestartIfChanged=false 307 '' else ""} 308 ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"} 309 ${attrsToSection def.serviceConfig} 310 ''; 311 }; 312 313 socketToUnit = name: def: 314 { inherit (def) wantedBy requiredBy enable; 315 text = commonUnitText def + 316 '' 317 [Socket] 318 ${attrsToSection def.socketConfig} 319 ${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)} 320 ''; 321 }; 322 323 timerToUnit = name: def: 324 { inherit (def) wantedBy requiredBy enable; 325 text = commonUnitText def + 326 '' 327 [Timer] 328 ${attrsToSection def.timerConfig} 329 ''; 330 }; 331 332 pathToUnit = name: def: 333 { inherit (def) wantedBy requiredBy enable; 334 text = commonUnitText def + 335 '' 336 [Path] 337 ${attrsToSection def.pathConfig} 338 ''; 339 }; 340 341 mountToUnit = name: def: 342 { inherit (def) wantedBy requiredBy enable; 343 text = commonUnitText def + 344 '' 345 [Mount] 346 ${attrsToSection def.mountConfig} 347 ''; 348 }; 349 350 automountToUnit = name: def: 351 { inherit (def) wantedBy requiredBy enable; 352 text = commonUnitText def + 353 '' 354 [Automount] 355 ${attrsToSection def.automountConfig} 356 ''; 357 }; 358 359in 360 361{ 362 363 ###### interface 364 365 options = { 366 367 systemd.package = mkOption { 368 default = pkgs.systemd; 369 type = types.package; 370 description = "The systemd package."; 371 }; 372 373 systemd.units = mkOption { 374 description = "Definition of systemd units."; 375 default = {}; 376 type = types.attrsOf types.optionSet; 377 options = { name, config, ... }: 378 { options = concreteUnitOptions; 379 config = { 380 unit = mkDefault (makeUnit name config); 381 }; 382 }; 383 }; 384 385 systemd.packages = mkOption { 386 default = []; 387 type = types.listOf types.package; 388 description = "Packages providing systemd units."; 389 }; 390 391 systemd.targets = mkOption { 392 default = {}; 393 type = types.attrsOf types.optionSet; 394 options = [ targetOptions unitConfig ]; 395 description = "Definition of systemd target units."; 396 }; 397 398 systemd.services = mkOption { 399 default = {}; 400 type = types.attrsOf types.optionSet; 401 options = [ serviceOptions unitConfig serviceConfig ]; 402 description = "Definition of systemd service units."; 403 }; 404 405 systemd.sockets = mkOption { 406 default = {}; 407 type = types.attrsOf types.optionSet; 408 options = [ socketOptions unitConfig ]; 409 description = "Definition of systemd socket units."; 410 }; 411 412 systemd.timers = mkOption { 413 default = {}; 414 type = types.attrsOf types.optionSet; 415 options = [ timerOptions unitConfig ]; 416 description = "Definition of systemd timer units."; 417 }; 418 419 systemd.paths = mkOption { 420 default = {}; 421 type = types.attrsOf types.optionSet; 422 options = [ pathOptions unitConfig ]; 423 description = "Definition of systemd path units."; 424 }; 425 426 systemd.mounts = mkOption { 427 default = []; 428 type = types.listOf types.optionSet; 429 options = [ mountOptions unitConfig mountConfig ]; 430 description = '' 431 Definition of systemd mount units. 432 This is a list instead of an attrSet, because systemd mandates the names to be derived from 433 the 'where' attribute. 434 ''; 435 }; 436 437 systemd.automounts = mkOption { 438 default = []; 439 type = types.listOf types.optionSet; 440 options = [ automountOptions unitConfig automountConfig ]; 441 description = '' 442 Definition of systemd automount units. 443 This is a list instead of an attrSet, because systemd mandates the names to be derived from 444 the 'where' attribute. 445 ''; 446 }; 447 448 systemd.generators = mkOption { 449 type = types.attrsOf types.path; 450 default = {}; 451 example = { "systemd-gpt-auto-generator" = "/dev/null"; }; 452 description = '' 453 Definition of systemd generators. 454 For each <literal>NAME = VALUE</literal> pair of the attrSet, a link is generated from 455 <literal>/etc/systemd/system-generators/NAME</literal> to <literal>VALUE</literal>. 456 ''; 457 }; 458 459 systemd.defaultUnit = mkOption { 460 default = "multi-user.target"; 461 type = types.str; 462 description = "Default unit started when the system boots."; 463 }; 464 465 systemd.globalEnvironment = mkOption { 466 type = types.attrs; 467 default = {}; 468 example = { TZ = "CET"; }; 469 description = '' 470 Environment variables passed to <emphasis>all</emphasis> systemd units. 471 ''; 472 }; 473 474 systemd.extraConfig = mkOption { 475 default = ""; 476 type = types.lines; 477 example = "DefaultLimitCORE=infinity"; 478 description = '' 479 Extra config options for systemd. See man systemd-system.conf for 480 available options. 481 ''; 482 }; 483 484 services.journald.console = mkOption { 485 default = ""; 486 type = types.str; 487 description = "If non-empty, write log messages to the specified TTY device."; 488 }; 489 490 services.journald.rateLimitInterval = mkOption { 491 default = "10s"; 492 type = types.str; 493 description = '' 494 Configures the rate limiting interval that is applied to all 495 messages generated on the system. This rate limiting is applied 496 per-service, so that two services which log do not interfere with 497 each other's limit. The value may be specified in the following 498 units: s, min, h, ms, us. To turn off any kind of rate limiting, 499 set either value to 0. 500 ''; 501 }; 502 503 services.journald.rateLimitBurst = mkOption { 504 default = 100; 505 type = types.int; 506 description = '' 507 Configures the rate limiting burst limit (number of messages per 508 interval) that is applied to all messages generated on the system. 509 This rate limiting is applied per-service, so that two services 510 which log do not interfere with each other's limit. 511 ''; 512 }; 513 514 services.journald.extraConfig = mkOption { 515 default = ""; 516 type = types.lines; 517 example = "Storage=volatile"; 518 description = '' 519 Extra config options for systemd-journald. See man journald.conf 520 for available options. 521 ''; 522 }; 523 524 services.journald.enableHttpGateway = mkOption { 525 default = false; 526 type = types.bool; 527 description = '' 528 Whether to enable the HTTP gateway to the journal. 529 ''; 530 }; 531 532 services.logind.extraConfig = mkOption { 533 default = ""; 534 type = types.lines; 535 example = "HandleLidSwitch=ignore"; 536 description = '' 537 Extra config options for systemd-logind. See man logind.conf for 538 available options. 539 ''; 540 }; 541 542 systemd.tmpfiles.rules = mkOption { 543 type = types.listOf types.str; 544 default = []; 545 example = [ "d /tmp 1777 root root 10d" ]; 546 description = '' 547 Rules for creating and cleaning up temporary files 548 automatically. See 549 <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> 550 for the exact format. You should not use this option to create 551 files required by systemd services, since there is no 552 guarantee that <command>systemd-tmpfiles</command> runs when 553 the system is reconfigured using 554 <command>nixos-rebuild</command>. 555 ''; 556 }; 557 558 systemd.user.units = mkOption { 559 description = "Definition of systemd per-user units."; 560 default = {}; 561 type = types.attrsOf types.optionSet; 562 options = { name, config, ... }: 563 { options = concreteUnitOptions; 564 config = { 565 unit = mkDefault (makeUnit name config); 566 }; 567 }; 568 }; 569 570 systemd.user.services = mkOption { 571 default = {}; 572 type = types.attrsOf types.optionSet; 573 options = [ serviceOptions unitConfig serviceConfig ]; 574 description = "Definition of systemd per-user service units."; 575 }; 576 577 systemd.user.timers = mkOption { 578 default = {}; 579 type = types.attrsOf types.optionSet; 580 options = [ timerOptions unitConfig ]; 581 description = "Definition of systemd per-user timer units."; 582 }; 583 584 systemd.user.sockets = mkOption { 585 default = {}; 586 type = types.attrsOf types.optionSet; 587 options = [ socketOptions unitConfig ]; 588 description = "Definition of systemd per-user socket units."; 589 }; 590 591 systemd.additionalUpstreamSystemUnits = mkOption { 592 default = [ ]; 593 type = types.listOf types.str; 594 example = [ "debug-shell.service" "systemd-quotacheck.service" ]; 595 description = '' 596 Additional units shipped with systemd that shall be enabled. 597 ''; 598 }; 599 600 }; 601 602 603 ###### implementation 604 605 config = { 606 607 warnings = concatLists (mapAttrsToList (name: service: 608 optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no") 609 "Service ${name}.service with Type=oneshot must have Restart=no") cfg.services); 610 611 system.build.units = cfg.units; 612 613 environment.systemPackages = [ systemd ]; 614 615 environment.etc = { 616 "systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants; 617 618 "systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits []; 619 620 "systemd/system.conf".text = '' 621 [Manager] 622 ${config.systemd.extraConfig} 623 ''; 624 625 "systemd/journald.conf".text = '' 626 [Journal] 627 RateLimitInterval=${config.services.journald.rateLimitInterval} 628 RateLimitBurst=${toString config.services.journald.rateLimitBurst} 629 ${optionalString (config.services.journald.console != "") '' 630 ForwardToConsole=yes 631 TTYPath=${config.services.journald.console} 632 ''} 633 ${config.services.journald.extraConfig} 634 ''; 635 636 "systemd/logind.conf".text = '' 637 [Login] 638 ${config.services.logind.extraConfig} 639 ''; 640 641 "systemd/sleep.conf".text = '' 642 [Sleep] 643 ''; 644 645 "tmpfiles.d/systemd.conf".source = "${systemd}/example/tmpfiles.d/systemd.conf"; 646 "tmpfiles.d/x11.conf".source = "${systemd}/example/tmpfiles.d/x11.conf"; 647 648 "tmpfiles.d/nixos.conf".text = '' 649 # This file is created automatically and should not be modified. 650 # Please change the option systemd.tmpfiles.rules instead. 651 652 ${concatStringsSep "\n" cfg.tmpfiles.rules} 653 ''; 654 } // mapAttrs' (n: v: nameValuePair "systemd/system-generators/${n}" {"source"=v;}) cfg.generators; 655 656 system.activationScripts.systemd = stringAfter [ "groups" ] 657 '' 658 mkdir -m 0755 -p /var/lib/udev 659 660 if ! [ -e /etc/machine-id ]; then 661 ${systemd}/bin/systemd-machine-id-setup 662 fi 663 664 # Keep a persistent journal. Note that systemd-tmpfiles will 665 # set proper ownership/permissions. 666 mkdir -m 0700 -p /var/log/journal 667 ''; 668 669 users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; 670 users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; 671 users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve; 672 users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve; 673 674 # Target for ‘charon send-keys’ to hook into. 675 users.extraGroups.keys.gid = config.ids.gids.keys; 676 677 systemd.targets.keys = 678 { description = "Security Keys"; 679 unitConfig.X-StopOnReconfiguration = true; 680 }; 681 682 systemd.targets.network-online.after = [ "ip-up.target" ]; 683 684 systemd.targets.network-pre = { 685 wantedBy = [ "network.target" ]; 686 before = [ "network.target" ]; 687 }; 688 689 systemd.targets.remote-fs-pre = { 690 wantedBy = [ "remote-fs.target" ]; 691 before = [ "remote-fs.target" ]; 692 }; 693 694 systemd.units = 695 mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets 696 // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services 697 // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets 698 // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers 699 // mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths 700 // listToAttrs (map 701 (v: let n = escapeSystemdPath v.where; 702 in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) 703 // listToAttrs (map 704 (v: let n = escapeSystemdPath v.where; 705 in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); 706 707 systemd.user.units = 708 mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services 709 // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets 710 // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.user.timers; 711 712 system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled 713 [ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET" 714 "SYSFS" "PROC_FS" "FHANDLE" "DMIID" "AUTOFS4_FS" "TMPFS_POSIX_ACL" 715 "TMPFS_XATTR" "SECCOMP" 716 ]; 717 718 environment.shellAliases = 719 { start = "systemctl start"; 720 stop = "systemctl stop"; 721 restart = "systemctl restart"; 722 status = "systemctl status"; 723 }; 724 725 users.extraGroups.systemd-journal.gid = config.ids.gids.systemd-journal; 726 users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; 727 users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; 728 729 # Generate timer units for all services that have a ‘startAt’ value. 730 systemd.timers = 731 mapAttrs (name: service: 732 { wantedBy = [ "timers.target" ]; 733 timerConfig.OnCalendar = service.startAt; 734 }) 735 (filterAttrs (name: service: service.startAt != "") cfg.services); 736 737 # Generate timer units for all services that have a ‘startAt’ value. 738 systemd.user.timers = 739 mapAttrs (name: service: 740 { wantedBy = [ "timers.target" ]; 741 timerConfig.OnCalendar = service.startAt; 742 }) 743 (filterAttrs (name: service: service.startAt != "") cfg.user.services); 744 745 systemd.sockets.systemd-journal-gatewayd.wantedBy = 746 optional config.services.journald.enableHttpGateway "sockets.target"; 747 748 # Provide the systemd-user PAM service, required to run systemd 749 # user instances. 750 security.pam.services.systemd-user = 751 { # Ensure that pam_systemd gets included. This is special-cased 752 # in systemd to provide XDG_RUNTIME_DIR. 753 startSession = true; 754 }; 755 756 # Some overrides to upstream units. 757 systemd.services."systemd-backlight@".restartIfChanged = false; 758 systemd.services."systemd-rfkill@".restartIfChanged = false; 759 systemd.services."user@".restartIfChanged = false; 760 systemd.services.systemd-journal-flush.restartIfChanged = false; 761 systemd.services.systemd-journald.restartIfChanged = false; # FIXME: shouldn't be necessary with systemd 219 762 systemd.services.systemd-random-seed.restartIfChanged = false; 763 systemd.services.systemd-remount-fs.restartIfChanged = false; 764 systemd.services.systemd-update-utmp.restartIfChanged = false; 765 systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions. 766 systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true; 767 systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true; 768 769 # Don't bother with certain units in containers. 770 systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container"; 771 systemd.services.systemd-random-seed.unitConfig.ConditionVirtualization = "!container"; 772 773 }; 774 775 # FIXME: Remove these eventually. 776 imports = 777 [ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ]) 778 (mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ]) 779 (mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ]) 780 ]; 781 782}