diff --git a/Makefile.am b/Makefile.am index 003ec9bfb7..f6699252d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -80,6 +80,8 @@ networkdir=$(rootprefix)/lib/systemd/network pkgincludedir=$(includedir)/systemd systemgeneratordir=$(rootlibexecdir)/system-generators usergeneratordir=$(prefix)/lib/systemd/user-generators +systemenvgeneratordir=$(prefix)/lib/systemd/system-environment-generators +userenvgeneratordir=$(prefix)/lib/systemd/user-environment-generators systemshutdowndir=$(rootlibexecdir)/system-shutdown systemsleepdir=$(rootlibexecdir)/system-sleep systemunitdir=$(rootprefix)/lib/systemd/system @@ -205,6 +207,8 @@ AM_CPPFLAGS = \ -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \ + -DSYSTEM_ENV_GENERATOR_PATH=\"$(systemenvgeneratordir)\" \ + -DUSER_ENV_GENERATOR_PATH=\"$(userenvgeneratordir)\" \ -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \ -DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \ -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \ @@ -6210,6 +6214,8 @@ substitutions = \ '|sysctldir=$(sysctldir)|' \ '|systemgeneratordir=$(systemgeneratordir)|' \ '|usergeneratordir=$(usergeneratordir)|' \ + '|systemenvgeneratordir=$(systemenvgeneratordir)|' \ + '|userenvgeneratordir=$(userenvgeneratordir)|' \ '|CERTIFICATEROOT=$(CERTIFICATEROOT)|' \ '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \ '|PACKAGE_NAME=$(PACKAGE_NAME)|' \ diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in index 8d7ce1c238..a2a7edd1ee 100644 --- a/src/core/macros.systemd.in +++ b/src/core/macros.systemd.in @@ -31,6 +31,8 @@ %_binfmtdir @binfmtdir@ %_systemdgeneratordir @systemgeneratordir@ %_systemdusergeneratordir @usergeneratordir@ +%_systemd_system_env_generator_dir @systemenvgeneratordir@ +%_systemd_user_env_generator_dir @userenvgeneratordir@ %systemd_requires \ Requires(post): systemd \ diff --git a/src/core/manager.c b/src/core/manager.c index 6bbda1af0d..aefe4ca780 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -103,6 +103,7 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32 static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata); static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata); static int manager_dispatch_run_queue(sd_event_source *source, void *userdata); +static int manager_run_environment_generators(Manager *m); static int manager_run_generators(Manager *m); static void manager_watch_jobs_in_progress(Manager *m) { @@ -1262,6 +1263,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { if (r < 0) return r; + r = manager_run_environment_generators(m); + if (r < 0) + return r; + /* Make sure the transient directory always exists, so that it remains in the search path */ if (!m->test_run) { r = mkdir_p_label(m->lookup_paths.transient, 0755); @@ -2795,6 +2800,10 @@ int manager_reload(Manager *m) { if (q < 0 && r >= 0) r = q; + q = manager_run_environment_generators(m); + if (q < 0 && r >= 0) + r = q; + /* Find new unit paths */ q = manager_run_generators(m); if (q < 0 && r >= 0) @@ -2986,10 +2995,56 @@ void manager_check_finished(Manager *m) { manager_invalidate_startup_units(m); } +static bool generator_path_any(const char* const* paths) { + char **path; + bool found = false; + + /* Optimize by skipping the whole process by not creating output directories + * if no generators are found. */ + STRV_FOREACH(path, (char**) paths) + if (access(*path, F_OK) == 0) + found = true; + else if (errno != ENOENT) + log_warning_errno(errno, "Failed to open generator directory %s: %m", *path); + + return found; +} + +static const char* system_env_generator_binary_paths[] = { + "/run/systemd/system-environment-generators", + "/etc/systemd/system-environment-generators", + "/usr/local/lib/systemd/system-environment-generators", + SYSTEM_ENV_GENERATOR_PATH, + NULL +}; + +static const char* user_env_generator_binary_paths[] = { + "/run/systemd/user-environment-generators", + "/etc/systemd/user-environment-generators", + "/usr/local/lib/systemd/user-environment-generators", + USER_ENV_GENERATOR_PATH, + NULL +}; + +static int manager_run_environment_generators(Manager *m) { + char **tmp = NULL; /* this is only used in the forked process, no cleanup here */ + const char **paths; + void* args[] = {&tmp, &tmp, &m->environment}; + + if (m->test_run) + return 0; + + paths = MANAGER_IS_SYSTEM(m) ? system_env_generator_binary_paths : user_env_generator_binary_paths; + + if (!generator_path_any(paths)) + return 0; + + return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL); +} + static int manager_run_generators(Manager *m) { _cleanup_strv_free_ char **paths = NULL; const char *argv[5]; - char **path; int r; assert(m); @@ -3001,18 +3056,9 @@ static int manager_run_generators(Manager *m) { if (!paths) return log_oom(); - /* Optimize by skipping the whole process by not creating output directories - * if no generators are found. */ - STRV_FOREACH(path, paths) { - if (access(*path, F_OK) >= 0) - goto found; - if (errno != ENOENT) - log_warning_errno(errno, "Failed to open generator directory %s: %m", *path); - } + if (!generator_path_any((const char* const*) paths)) + return 0; - return 0; - - found: r = lookup_paths_mkdir_generator(&m->lookup_paths); if (r < 0) goto finish;