]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: rework environment block copy logic
authorLennart Poettering <lennart@poettering.net>
Fri, 1 Nov 2019 10:26:05 +0000 (11:26 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 1 Nov 2019 10:30:59 +0000 (11:30 +0100)
This reworks the logic introduced in
a5cede8c24fddda9b73f142e09b18b49adde1b9c (#13693).

First of all, let's move this out of util.c, since only PID 1 really
needs this, and there's no real need to have it in util.c.

Then, fix freeing of the variable. It previously relied on
STATIC_DESTRUCTOR_REGISTER() which however relies on static_destruct()
to be called explicitly. Currently only the main-func.h macros do that,
and PID 1 does not. (It might be worth investigating whether to do that,
but it's not trivial.) Hence the freeing wasn't applied.

Finally, an OOM check was missing, add it in.

src/basic/util.c
src/basic/util.h
src/core/main.c

index b02471c483acf3e42e43cddc96993b9f6e660222..f74ed95a609e39fc578bb35b9f5cd1dc1fb9026c 100644 (file)
@@ -38,7 +38,6 @@
 #include "set.h"
 #include "signal-util.h"
 #include "stat-util.h"
-#include "static-destruct.h"
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
 
 int saved_argc = 0;
 char **saved_argv = NULL;
-char **saved_env = NULL;
 static int saved_in_initrd = -1;
 
-STATIC_DESTRUCTOR_REGISTER(saved_env, strv_freep);
-
 bool kexec_loaded(void) {
        _cleanup_free_ char *s = NULL;
 
@@ -301,7 +297,3 @@ void disable_coredumps(void) {
         if (r < 0)
                 log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
 }
-
-void save_env(void) {
-        saved_env = strv_copy(environ);
-}
index 15444b2e5c576c9d524cb2258521c1a460cc0201..6fc7480fcbd7697b6101832f301a766f78dbd03d 100644 (file)
@@ -13,9 +13,6 @@ static inline void save_argc_argv(int argc, char **argv) {
         saved_argv = argv;
 }
 
-extern char **saved_env;
-void save_env(void);
-
 bool kexec_loaded(void);
 
 int prot_from_flags(int flags) _const_;
index 7c814f3237045c311543b6e1c1f26f8acbef7cc1..3545fde71d43f5723e193f209a86c579e90b67e2 100644 (file)
@@ -146,6 +146,9 @@ static OOMPolicy arg_default_oom_policy;
 static CPUSet arg_cpu_affinity;
 static NUMAPolicy arg_numa_policy;
 
+/* A copy of the original environment block */
+static char **saved_env = NULL;
+
 static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
                                const struct rlimit *saved_rlimit_memlock);
 
@@ -2353,6 +2356,17 @@ static bool early_skip_setup_check(int argc, char *argv[]) {
         return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */
 }
 
+static int save_env(void) {
+        char **l;
+
+        l = strv_copy(environ);
+        if (!l)
+                return -ENOMEM;
+
+        strv_free_and_replace(saved_env, l);
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
 
         dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL,
@@ -2391,9 +2405,13 @@ int main(int argc, char *argv[]) {
         /* Save the original command line */
         save_argc_argv(argc, argv);
 
-        /* Save the original environment as we might need to restore it if we're requested to
-         * execute another system manager later. */
-        save_env();
+        /* Save the original environment as we might need to restore it if we're requested to execute another
+         * system manager later. */
+        r = save_env();
+        if (r < 0) {
+                error_message = "Failed to copy environment block";
+                goto finish;
+        }
 
         /* Make sure that if the user says "syslog" we actually log to the journal. */
         log_set_upgrade_syslog_to_journal(true);
@@ -2681,6 +2699,8 @@ finish:
         arg_serialization = safe_fclose(arg_serialization);
         fds = fdset_free(fds);
 
+        saved_env = strv_free(saved_env);
+
 #if HAVE_VALGRIND_VALGRIND_H
         /* If we are PID 1 and running under valgrind, then let's exit
          * here explicitly. valgrind will only generate nice output on