diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index 0811e1909e..d39928ec23 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -323,11 +323,10 @@
DefaultEnvironment=
- Sets manager environment variables passed to
- all executed processes. Takes a space-separated list of
- variable assignments. See
- environ7
- for details about environment variables.
+ Configures environment variables passed to all executed processes. Takes a
+ space-separated list of variable assignments. See environ7 for
+ details about environment variables.
Example:
@@ -339,6 +338,20 @@
VAR3.
+
+ ManagerEnvironment=
+
+ Takes the same arguments as DefaultEnvironment=, see above. Sets
+ environment variables just for the manager process itself. These variables are not inherited by
+ processes spawned by the service manager, use DefaultEnvironment= for that. Note
+ that these variables are merged into the existing environment block. In particular, in case of the
+ system manager, this includes variables set by the kernel based on the kernel command line.
+
+ Setting environment variables for the manager process may be useful to modify its behaviour.
+ See ENVIRONMENT for a descriptions of some
+ variables understood by systemd.
+
+
DefaultCPUAccounting=
DefaultBlockIOAccounting=
diff --git a/src/core/main.c b/src/core/main.c
index 2237925209..12ac2ba3c6 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -134,6 +134,7 @@ static usec_t arg_kexec_watchdog;
static char *arg_early_core_pattern;
static char *arg_watchdog_device;
static char **arg_default_environment;
+static char **arg_manager_environment;
static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
static uint64_t arg_capability_bounding_set;
static bool arg_no_new_privs;
@@ -670,6 +671,7 @@ static int parse_config_file(void) {
{ "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_default_start_limit_interval },
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
{ "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
+ { "Manager", "ManagerEnvironment", config_parse_environ, 0, &arg_manager_environment },
{ "Manager", "DefaultLimitCPU", config_parse_rlimit, RLIMIT_CPU, arg_default_rlimit },
{ "Manager", "DefaultLimitFSIZE", config_parse_rlimit, RLIMIT_FSIZE, arg_default_rlimit },
{ "Manager", "DefaultLimitDATA", config_parse_rlimit, RLIMIT_DATA, arg_default_rlimit },
@@ -2301,6 +2303,19 @@ static void fallback_rlimit_memlock(const struct rlimit *saved_rlimit_memlock) {
arg_default_rlimit[RLIMIT_MEMLOCK] = rl;
}
+static void setenv_manager_environment(void) {
+ char **p;
+ int r;
+
+ STRV_FOREACH(p, arg_manager_environment) {
+ log_debug("Setting '%s' in our own environment.", *p);
+
+ r = putenv_dup(*p, true);
+ if (r < 0)
+ log_warning_errno(errno, "Failed to setenv \"%s\", ignoring: %m", *p);
+ }
+}
+
static void reset_arguments(void) {
/* Frees/resets arg_* variables, with a few exceptions commented below. */
@@ -2334,6 +2349,7 @@ static void reset_arguments(void) {
arg_watchdog_device = NULL;
arg_default_environment = strv_free(arg_default_environment);
+ arg_manager_environment = strv_free(arg_manager_environment);
rlimit_free_all(arg_default_rlimit);
arg_capability_bounding_set = CAP_ALL;
@@ -2395,6 +2411,9 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
if (arg_show_status == _SHOW_STATUS_INVALID)
arg_show_status = SHOW_STATUS_YES;
+ /* Push variables into the manager environment block */
+ setenv_manager_environment();
+
return 0;
}