summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/config/sysctl.nix13
-rw-r--r--nixos/modules/services/hardware/udev.nix3
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix20
-rw-r--r--nixos/modules/services/ttys/agetty.nix9
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl10
-rw-r--r--nixos/modules/system/boot/kernel.nix33
-rw-r--r--nixos/modules/system/boot/systemd-unit-options.nix6
-rw-r--r--nixos/modules/system/boot/systemd.nix59
-rw-r--r--nixos/modules/tasks/kbd.nix14
9 files changed, 71 insertions, 96 deletions
diff --git a/nixos/modules/config/sysctl.nix b/nixos/modules/config/sysctl.nix
index b4cd22caa79..54236021919 100644
--- a/nixos/modules/config/sysctl.nix
+++ b/nixos/modules/config/sysctl.nix
@@ -45,19 +45,8 @@ in
       ) config.boot.kernel.sysctl);
 
     systemd.services.systemd-sysctl =
-      { description = "Apply Kernel Variables";
-        before = [ "sysinit.target" "shutdown.target" ];
-        wantedBy = [ "sysinit.target" "multi-user.target" ];
+      { wantedBy = [ "multi-user.target" ];
         restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ];
-        unitConfig = {
-          DefaultDependencies = false; # needed to prevent a cycle
-          ConditionPathIsReadWrite = "/proc/sys/"; # prevent systemd-sysctl in containers
-        };
-        serviceConfig = {
-          Type = "oneshot";
-          RemainAfterExit = true;
-          ExecStart = "${config.systemd.package}/lib/systemd/systemd-sysctl";
-        };
       };
 
     # Enable hardlink and symlink restrictions.  See
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index 875de55b6c6..169a2e88414 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -244,8 +244,7 @@ in
       '';
 
     systemd.services.systemd-udevd =
-      { baseUnit = "${config.systemd.package}/example/systemd/system/systemd-udevd.service";
-        environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
+      { environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
       };
 
   };
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index 1516736dc2e..e6528777c32 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -275,28 +275,16 @@ in
           ) cfg.buildMachines;
       };
 
-    systemd.sockets."nix-daemon" =
-      { description = "Nix Daemon Socket";
-        wantedBy = [ "sockets.target" ];
-        before = [ "multi-user.target" ];
-        unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket/";
-        socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket";
-      };
-
-    systemd.services."nix-daemon" =
-      { description = "Nix Daemon";
+    systemd.packages = [ nix ];
 
-        path = [ nix pkgs.openssl pkgs.utillinux pkgs.openssh ]
+    systemd.services.nix-daemon =
+      { path = [ nix pkgs.openssl pkgs.utillinux pkgs.openssh ]
           ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
 
         environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; };
 
-        unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket/";
-
         serviceConfig =
-          { ExecStart = "@${nix}/bin/nix-daemon nix-daemon --daemon";
-            KillMode = "process";
-            Nice = cfg.daemonNiceLevel;
+          { Nice = cfg.daemonNiceLevel;
             IOSchedulingPriority = cfg.daemonIONiceLevel;
             LimitNOFILE = 4096;
           };
diff --git a/nixos/modules/services/ttys/agetty.nix b/nixos/modules/services/ttys/agetty.nix
index c4571ef856f..df21ebbd974 100644
--- a/nixos/modules/services/ttys/agetty.nix
+++ b/nixos/modules/services/ttys/agetty.nix
@@ -49,22 +49,19 @@ with lib;
   config = {
 
     systemd.services."getty@" =
-      { baseUnit = "${config.systemd.package}/example/systemd/system/getty@.service";
-        serviceConfig.ExecStart = "@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login --keep-baud %I 115200,38400,9600 $TERM";
+      { serviceConfig.ExecStart = "@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login --keep-baud %I 115200,38400,9600 $TERM";
         restartIfChanged = false;
       };
 
     systemd.services."serial-getty@" =
-      { baseUnit = "${config.systemd.package}/example/systemd/system/serial-getty@.service";
-        serviceConfig.ExecStart =
+      { serviceConfig.ExecStart =
           let speeds = concatStringsSep "," (map toString config.services.mingetty.serialSpeed);
           in "@${pkgs.utillinux}/sbin/agetty agetty --login-program ${pkgs.shadow}/bin/login %I ${speeds} $TERM";
         restartIfChanged = false;
       };
 
     systemd.services."container-getty@" =
-      { baseUnit = "${config.systemd.package}/example/systemd/system/container-getty@.service";
-        unitConfig.ConditionPathExists = "/dev/pts/%I"; # Work around being respawned when "machinectl login" exits.
+      { unitConfig.ConditionPathExists = "/dev/pts/%I"; # Work around being respawned when "machinectl login" exits.
         serviceConfig.ExecStart = "@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login --keep-baud pts/%I 115200,38400,9600 $TERM";
         restartIfChanged = false;
       };
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index fd2b5b7950d..13bd0b60f82 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -115,6 +115,14 @@ sub boolIsTrue {
     return $s eq "yes" || $s eq "true";
 }
 
+# As a fingerprint for determining whether a unit has changed, we use
+# its absolute path. If it has an override file, we append *its*
+# absolute path as well.
+sub fingerprintUnit {
+    my ($s) = @_;
+    return abs_path($s) . (-f "${s}.d/overrides.conf" ? " " . abs_path "${s}.d/overrides.conf" : "");
+}
+
 # Stop all services that no longer exist or have changed in the new
 # configuration.
 my (@unitsToStop, @unitsToSkip);
@@ -166,7 +174,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
             }
         }
 
-        elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
+        elsif (fingerprintUnit($prevUnitFile) ne fingerprintUnit($newUnitFile)) {
             if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
                 # Do nothing.  These cannot be restarted directly.
             } elsif ($unit =~ /\.mount$/) {
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index 2e036fafae6..5e5b2abbb9c 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -147,12 +147,6 @@ in
 
   config = mkIf (!config.boot.isContainer) {
 
-    systemd.services.kmod-static-nodes =
-      { wantedBy = [ "sysinit.target" ];
-        baseUnit = "${config.systemd.package}/example/systemd/system/kmod-static-nodes.service";
-        environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
-      };
-
     system.build = { inherit kernel; };
 
     system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages;
@@ -224,37 +218,26 @@ in
 
     # Create /etc/modules-load.d/nixos.conf, which is read by
     # systemd-modules-load.service to load required kernel modules.
-    # FIXME: ensure that systemd-modules-load.service is restarted if
-    # this file changes.
     environment.etc = singleton
       { target = "modules-load.d/nixos.conf";
         source = kernelModulesConf;
       };
 
-    # Sigh.  This overrides systemd's systemd-modules-load.service
-    # just so we can set a restart trigger.  Also make
-    # multi-user.target pull it in so that it gets started if it
-    # failed earlier.
     systemd.services."systemd-modules-load" =
-      { description = "Load Kernel Modules";
-        wantedBy = [ "sysinit.target" "multi-user.target" ];
-        before = [ "sysinit.target" "shutdown.target" ];
-        conflicts = [ "shutdown.target" ];
-        unitConfig =
-          { DefaultDependencies = false;
-            ConditionCapability = "CAP_SYS_MODULE";
-          };
+      { wantedBy = [ "multi-user.target" ];
+        restartTriggers = [ kernelModulesConf ];
+        environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
         serviceConfig =
-          { Type = "oneshot";
-            RemainAfterExit = true;
-            ExecStart = "${config.systemd.package}/lib/systemd/systemd-modules-load";
-            # Ignore failed module loads.  Typically some of the
+          { # Ignore failed module loads.  Typically some of the
             # modules in ‘boot.kernelModules’ are "nice to have but
             # not required" (e.g. acpi-cpufreq), so we don't want to
             # barf on those.
             SuccessExitStatus = "0 1";
           };
-        restartTriggers = [ kernelModulesConf ];
+      };
+
+    systemd.services.kmod-static-nodes =
+      { wantedBy = [ "sysinit.target" ];
         environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
       };
 
diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index 20ea0ba874d..a16263b390d 100644
--- a/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixos/modules/system/boot/systemd-unit-options.nix
@@ -41,12 +41,6 @@ in rec {
       '';
     };
 
-    baseUnit = mkOption {
-      type = types.nullOr types.path;
-      default = null;
-      description = "Path to an upstream unit file on which the NixOS unit configuration will be based.";
-    };
-
     description = mkOption {
       default = "";
       type = types.str;
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 5d144a3642b..ee809a8ec44 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -31,7 +31,6 @@ let
       "sockets.target"
       "graphical.target"
       "multi-user.target"
-      "getty.target"
       "network.target"
       "network-online.target"
       "nss-lookup.target"
@@ -50,10 +49,17 @@ let
       # Udev.
       "systemd-udevd-control.socket"
       "systemd-udevd-kernel.socket"
-      #"systemd-udevd.service"
+      "systemd-udevd.service"
       "systemd-udev-settle.service"
       "systemd-udev-trigger.service"
 
+      # Consoles.
+      "getty.target"
+      "getty@.service"
+      "serial-getty@.service"
+      "container-getty@.service"
+      "systemd-vconsole-setup.service"
+
       # Hardware (started by udev when a relevant device is plugged in).
       "sound.target"
       "bluetooth.target"
@@ -80,7 +86,8 @@ let
       "systemd-initctl.service"
 
       # Kernel module loading.
-      #"systemd-modules-load.service"
+      "systemd-modules-load.service"
+      "kmod-static-nodes.service"
 
       # Filesystems.
       "systemd-fsck@.service"
@@ -146,6 +153,9 @@ let
       "systemd-tmpfiles-clean.timer"
       "systemd-tmpfiles-setup.service"
       "systemd-tmpfiles-setup-dev.service"
+
+      # Misc.
+      "systemd-sysctl.service"
     ]
 
     ++ optionals cfg.enableEmergencyMode [
@@ -198,7 +208,7 @@ let
 
   serviceConfig = { name, config, ... }: {
     config = mkMerge
-      [ (mkIf (config.baseUnit == null) { # Default path for systemd services.  Should be quite minimal.
+      [ { # Default path for systemd services.  Should be quite minimal.
           path =
             [ pkgs.coreutils
               pkgs.findutils
@@ -207,7 +217,7 @@ let
               systemd
             ];
           environment.PATH = config.path;
-        })
+        }
         (mkIf (config.preStart != "")
           { serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" ''
               #! ${pkgs.stdenv.shell} -e
@@ -275,10 +285,7 @@ let
         (if isList value then value else [value]))
         as));
 
-  commonUnitText = def:
-    optionalString (def.baseUnit != null) ''
-      .include ${def.baseUnit}
-    '' + ''
+  commonUnitText = def: ''
       [Unit]
       ${attrsToSection def.unitConfig}
     '';
@@ -358,6 +365,8 @@ let
   units = pkgs.runCommand "units" { preferLocalBuild = true; }
     ''
       mkdir -p $out
+
+      # Copy the upstream systemd units we're interested in.
       for i in ${toString upstreamUnits}; do
         fn=${systemd}/example/systemd/system/$i
         if ! [ -e $fn ]; then echo "missing $fn"; false; fi
@@ -368,6 +377,8 @@ let
         fi
       done
 
+      # Copy .wants links, but only those that point to units that
+      # we're interested in.
       for i in ${toString upstreamWants}; do
         fn=${systemd}/example/systemd/system/$i
         if ! [ -e $fn ]; then echo "missing $fn"; false; fi
@@ -376,18 +387,35 @@ let
         for i in $fn/*; do
           y=$x/$(basename $i)
           cp -pd $i $y
-          if ! [ -e $y ]; then rm -v $y; fi
+          if ! [ -e $y ]; then rm $y; fi
         done
       done
 
-      for i in ${toString (mapAttrsToList (n: v: v.unit) cfg.units)}; do
-        ln -fs $i/* $out/
+      # Symlink all units provided listed in systemd.packages.
+      for i in ${toString cfg.packages}; do
+        ln -s $i/etc/systemd/system/* $i/lib/systemd/system/* $out/
       done
 
-      for i in ${toString cfg.packages}; do
-        ln -s $i/etc/systemd/system/* $out/
+      # Symlink all units defined by systemd.units. If these are also
+      # provided by systemd or systemd.packages, then add them as
+      # <unit-name>.d/overrides.conf, which makes them extend the
+      # upstream unit.
+      for i in ${toString (mapAttrsToList (n: v: v.unit) cfg.units)}; do
+        fn=$(basename $i/*)
+        if [ -e $out/$fn ]; then
+          if [ "$(readlink -f $i/$fn)" = /dev/null ]; then
+            ln -sfn /dev/null $out/$fn
+          else
+            mkdir $out/$fn.d
+            ln -s $i/$fn $out/$fn.d/overrides.conf
+          fi
+       else
+          ln -fs $i/$fn $out/
+        fi
       done
 
+      # Created .wants and .requires symlinks from the wantedBy and
+      # requiredBy options.
       ${concatStrings (mapAttrsToList (name: unit:
           concatMapStrings (name2: ''
             mkdir -p $out/'${name2}.wants'
@@ -400,6 +428,7 @@ let
             ln -sfn '../${name}' $out/'${name2}.requires'/
           '') unit.requiredBy) cfg.units)}
 
+      # Stupid misc. symlinks.
       ln -s ${cfg.defaultUnit} $out/default.target
 
       ln -s rescue.target $out/kbrequest.target
@@ -411,7 +440,7 @@ let
             ../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
 
       ${ optionalString config.services.journald.enableHttpGateway ''
-      ln -s ../systemd-journal-gatewayd.service $out/multi-user-target.wants/
+        ln -s ../systemd-journal-gatewayd.service $out/multi-user-target.wants/
       ''}
     ''; # */
 
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index df4737305da..03c42404e5d 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -52,19 +52,7 @@ in
     # /dev/tty0 to prevent putting the X server in non-raw mode, and
     # it has a restart trigger.
     systemd.services."systemd-vconsole-setup" =
-      { description = "Setup Virtual Console";
-        wantedBy = [ "sysinit.target" "multi-user.target" ];
-        before = [ "sysinit.target" "shutdown.target" ];
-        conflicts = [ "shutdown.target" ];
-        unitConfig =
-          { DefaultDependencies = "no";
-            ConditionPathExists = "/dev/tty1";
-          };
-        serviceConfig =
-          { Type = "oneshot";
-            RemainAfterExit = true;
-            ExecStart = "${config.systemd.package}/lib/systemd/systemd-vconsole-setup /dev/tty1";
-          };
+      { wantedBy = [ "multi-user.target" ];
         restartTriggers = [ vconsoleConf ];
       };