nixos/systemd: Switch to ManagerEnvironment=
This accomplishes multiple things: - Allows us to start systemd without stage-2-init.sh. This was not possible before because the environment would have been wrong - `systemctl daemon-reexec` also changes the environment, giving us newer tools for the fs packages - Starts systemd in a fully clean environment, making everything more consistent and pure
This commit is contained in:
parent
d56076aa39
commit
a3e0698bf6
@ -167,10 +167,6 @@ exec 1>&$logOutFd 2>&$logErrFd
|
||||
exec {logOutFd}>&- {logErrFd}>&-
|
||||
|
||||
|
||||
# Start systemd.
|
||||
# Start systemd in a clean environment.
|
||||
echo "starting systemd..."
|
||||
|
||||
PATH=/run/current-system/systemd/lib/systemd:@fsPackagesPath@ \
|
||||
LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive @systemdUnitPathEnvVar@ \
|
||||
TZDIR=/etc/zoneinfo \
|
||||
exec @systemdExecutable@
|
||||
exec env - @systemdExecutable@ "$@"
|
||||
|
@ -19,11 +19,6 @@ let
|
||||
pkgs.coreutils
|
||||
pkgs.util-linux
|
||||
] ++ lib.optional useHostResolvConf pkgs.openresolv);
|
||||
fsPackagesPath = lib.makeBinPath config.system.fsPackages;
|
||||
systemdUnitPathEnvVar = lib.optionalString (config.boot.extraSystemdUnitPaths != [])
|
||||
("SYSTEMD_UNIT_PATH="
|
||||
+ builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths
|
||||
+ ":"); # If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
||||
postBootCommands = pkgs.writeText "local-cmds"
|
||||
''
|
||||
${config.boot.postBootCommands}
|
||||
@ -78,12 +73,10 @@ in
|
||||
};
|
||||
|
||||
systemdExecutable = mkOption {
|
||||
default = "systemd";
|
||||
default = "/run/current-system/systemd/lib/systemd/systemd";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The program to execute to start systemd. Typically
|
||||
<literal>systemd</literal>, which will find systemd in the
|
||||
PATH.
|
||||
The program to execute to start systemd.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -302,6 +302,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.managerEnvironment = mkOption {
|
||||
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
|
||||
default = {};
|
||||
example = { SYSTEMD_LOG_LEVEL = "debug"; };
|
||||
description = ''
|
||||
Environment variables of PID 1. These variables are
|
||||
<emphasis>not</emphasis> passed to started units.
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.enableCgroupAccounting = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
@ -470,11 +480,13 @@ in
|
||||
|
||||
enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
|
||||
enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units;
|
||||
|
||||
in ({
|
||||
"systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
|
||||
|
||||
"systemd/system.conf".text = ''
|
||||
[Manager]
|
||||
ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)}
|
||||
${optionalString config.systemd.enableCgroupAccounting ''
|
||||
DefaultCPUAccounting=yes
|
||||
DefaultIOAccounting=yes
|
||||
@ -542,6 +554,17 @@ in
|
||||
(v: let n = escapeSystemdPath v.where;
|
||||
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
|
||||
|
||||
# Environment of PID 1
|
||||
systemd.managerEnvironment = {
|
||||
# Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools
|
||||
PATH = lib.makeBinPath config.system.fsPackages;
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
TZDIR = "/etc/zoneinfo";
|
||||
# If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
||||
SYSTEMD_UNIT_PATH = lib.mkIf (config.boot.extraSystemdUnitPaths != []) "${builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths}:";
|
||||
};
|
||||
|
||||
|
||||
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
|
||||
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
|
||||
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
|
||||
|
@ -192,5 +192,9 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
with subtest("systemd per-unit accounting works"):
|
||||
assert "IP traffic received: 84B" in output_ping
|
||||
assert "IP traffic sent: 84B" in output_ping
|
||||
|
||||
with subtest("systemd environment is properly set"):
|
||||
machine.systemctl("daemon-reexec") # Rewrites /proc/1/environ
|
||||
machine.succeed("grep -q TZDIR=/etc/zoneinfo /proc/1/environ")
|
||||
'';
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user