From: Lennart Poettering Date: Tue, 12 Apr 2022 13:44:46 +0000 (+0200) Subject: pid1: pass useful env vars to generators X-Git-Tag: v251-rc2~132^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82c5db16cc843d2fcee54ccf88c5a92ab059321d;p=thirdparty%2Fsystemd.git pid1: pass useful env vars to generators This is inspired by this: https://github.com/systemd/zram-generator/blob/main/src/generator.rs#L29 Given it's easy for PID 1 to pass this to generators, I thin we should. All generators not written by us likely want to know these things so that the can adjust to the execution environment. --- diff --git a/src/core/manager.c b/src/core/manager.c index 2f60b141590..a68324affc5 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -3665,9 +3665,67 @@ static int manager_run_environment_generators(Manager *m) { return r; } +static int build_generator_environment(Manager *m, char ***ret) { + _cleanup_strv_free_ char **nl = NULL; + Virtualization v; + int r; + + assert(m); + assert(ret); + + /* Generators oftentimes want to know some basic facts about the environment they run in, in order to + * adjust generated units to that. Let's pass down some bits of information that are easy for us to + * determine (but a bit harder for generator scripts to determine), as environment variables. */ + + nl = strv_copy(m->transient_environment); + if (!nl) + return -ENOMEM; + + r = strv_env_assign(&nl, "SYSTEMD_SCOPE", MANAGER_IS_SYSTEM(m) ? "system" : "user"); + if (r < 0) + return r; + + if (MANAGER_IS_SYSTEM(m)) { + /* Note that $SYSTEMD_IN_INITRD may be used to override the initrd detection in much of our + * codebase. This is hence more than purely informational. It will shortcut detection of the + * initrd state if generators invoke our own tools. But that's OK, as it would come to the + * same results (hopefully). */ + r = strv_env_assign(&nl, "SYSTEMD_IN_INITRD", one_zero(in_initrd())); + if (r < 0) + return r; + + if (m->first_boot >= 0) { + r = strv_env_assign(&nl, "SYSTEMD_FIRST_BOOT", one_zero(m->first_boot)); + if (r < 0) + return r; + } + } + + v = detect_virtualization(); + if (v < 0) + log_debug_errno(v, "Failed to detect virtualization, ignoring: %m"); + else if (v > 0) { + const char *s; + + s = strjoina(VIRTUALIZATION_IS_VM(v) ? "vm:" : + VIRTUALIZATION_IS_CONTAINER(v) ? "container:" : ":", + virtualization_to_string(v)); + + r = strv_env_assign(&nl, "SYSTEMD_VIRTUALIZATION", s); + if (r < 0) + return r; + } + + r = strv_env_assign(&nl, "SYSTEMD_ARCHITECTURE", architecture_to_string(uname_architecture())); + if (r < 0) + return r; + + *ret = TAKE_PTR(nl); + return 0; +} + static int manager_run_generators(Manager *m) { - _cleanup_strv_free_ char **paths = NULL; - const char *argv[5]; + _cleanup_strv_free_ char **paths = NULL, **ge = NULL; int r; assert(m); @@ -3688,16 +3746,28 @@ static int manager_run_generators(Manager *m) { goto finish; } - argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */ - argv[1] = m->lookup_paths.generator; - argv[2] = m->lookup_paths.generator_early; - argv[3] = m->lookup_paths.generator_late; - argv[4] = NULL; + const char *argv[] = { + NULL, /* Leave this empty, execute_directory() will fill something in */ + m->lookup_paths.generator, + m->lookup_paths.generator_early, + m->lookup_paths.generator_late, + NULL, + }; + + r = build_generator_environment(m, &ge); + if (r < 0) { + log_error_errno(r, "Failed to build generator environment: %m"); + goto finish; + } RUN_WITH_UMASK(0022) - (void) execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, NULL, NULL, - (char**) argv, m->transient_environment, - EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS | EXEC_DIR_SET_SYSTEMD_EXEC_PID); + (void) execute_directories( + (const char* const*) paths, + DEFAULT_TIMEOUT_USEC, + /* callbacks= */ NULL, /* callback_args= */ NULL, + (char**) argv, + ge, + EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS | EXEC_DIR_SET_SYSTEMD_EXEC_PID); r = 0;