Blame SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch

ddca0b
From 0387294ba41ceaf80c79621409aab9508732bda0 Mon Sep 17 00:00:00 2001
ddca0b
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
ddca0b
Date: Fri, 24 May 2019 09:41:44 +0200
ddca0b
Subject: [PATCH] pid1: when reloading configuration, forget old settings
ddca0b
ddca0b
If we had a configuration setting from a configuration file, and it was
ddca0b
removed, we'd still remember the old value, because there's was no mechanism to
ddca0b
"reset" everything, just to assign new values.
ddca0b
ddca0b
Note that the effect of this is limited. For settings that have an "ongoing" effect,
ddca0b
like systemd.confirm_spawn, the new value is simply used. But some settings can only
ddca0b
be set at start.
ddca0b
ddca0b
In particular, CPUAffinity= will be updated if set to a new value, but if
ddca0b
CPUAffinity= is fully removed, it will not be reset, simply because we don't
ddca0b
know what to reset it to. We might have inherited a setting, or we might have
ddca0b
set it ourselves. In principle we could remember the "original" value that was
ddca0b
set when we were executed, but propagate this over reloads and reexecs, but
ddca0b
that would be a lot of work for little gain. So this corner case of removal of
ddca0b
CPUAffinity= is not handled fully, and a reboot is needed to execute the
ddca0b
change. As a work-around, a full mask of CPUAffinity=0-8191 can be specified.
ddca0b
ddca0b
(cherry picked from commit fb39af4ce42d7ef9af63009f271f404038703704)
ddca0b
ddca0b
Related: #1734787
ddca0b
---
ddca0b
 src/core/main.c | 139 +++++++++++++++++++++++++++++++++---------------
ddca0b
 1 file changed, 95 insertions(+), 44 deletions(-)
ddca0b
ddca0b
diff --git a/src/core/main.c b/src/core/main.c
ddca0b
index 9a9f145080..c74dc641c1 100644
ddca0b
--- a/src/core/main.c
ddca0b
+++ b/src/core/main.c
ddca0b
@@ -88,46 +88,52 @@ static enum {
ddca0b
         ACTION_DUMP_CONFIGURATION_ITEMS,
ddca0b
         ACTION_DUMP_BUS_PROPERTIES,
ddca0b
 } arg_action = ACTION_RUN;
ddca0b
-static char *arg_default_unit = NULL;
ddca0b
-static bool arg_system = false;
ddca0b
-static bool arg_dump_core = true;
ddca0b
-static int arg_crash_chvt = -1;
ddca0b
-static bool arg_crash_shell = false;
ddca0b
-static bool arg_crash_reboot = false;
ddca0b
-static char *arg_confirm_spawn = NULL;
ddca0b
-static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
ddca0b
-static bool arg_switched_root = false;
ddca0b
-static bool arg_no_pager = false;
ddca0b
-static bool arg_service_watchdogs = true;
ddca0b
+
ddca0b
+/* Those variables are initalized to 0 automatically, so we avoid uninitialized memory access.
ddca0b
+ * Real defaults are assigned in reset_arguments() below. */
ddca0b
+static char *arg_default_unit;
ddca0b
+static bool arg_system;
ddca0b
+static bool arg_dump_core;
ddca0b
+static int arg_crash_chvt;
ddca0b
+static bool arg_crash_shell;
ddca0b
+static bool arg_crash_reboot;
ddca0b
+static char *arg_confirm_spawn;
ddca0b
+static ShowStatus arg_show_status;
ddca0b
+static bool arg_switched_root;
ddca0b
+static bool arg_no_pager;
ddca0b
+static bool arg_service_watchdogs;
ddca0b
 static char ***arg_join_controllers = NULL;
ddca0b
-static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
ddca0b
-static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
ddca0b
-static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
ddca0b
-static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
ddca0b
-static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
ddca0b
-static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
ddca0b
-static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
ddca0b
-static usec_t arg_runtime_watchdog = 0;
ddca0b
-static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
ddca0b
-static char *arg_watchdog_device = NULL;
ddca0b
-static char **arg_default_environment = NULL;
ddca0b
-static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
ddca0b
-static uint64_t arg_capability_bounding_set = CAP_ALL;
ddca0b
-static bool arg_no_new_privs = false;
ddca0b
-static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
ddca0b
-static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
ddca0b
-static Set* arg_syscall_archs = NULL;
ddca0b
-static FILE* arg_serialization = NULL;
ddca0b
-static bool arg_default_cpu_accounting = false;
ddca0b
-static bool arg_default_io_accounting = false;
ddca0b
-static bool arg_default_ip_accounting = false;
ddca0b
-static bool arg_default_blockio_accounting = false;
ddca0b
-static bool arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
ddca0b
-static bool arg_default_tasks_accounting = true;
ddca0b
-static uint64_t arg_default_tasks_max = UINT64_MAX;
ddca0b
-static sd_id128_t arg_machine_id = {};
ddca0b
-static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
ddca0b
-static CPUSet arg_cpu_affinity = {};
ddca0b
+static ExecOutput arg_default_std_output;
ddca0b
+static ExecOutput arg_default_std_error;
ddca0b
+static usec_t arg_default_restart_usec;
ddca0b
+static usec_t arg_default_timeout_start_usec;
ddca0b
+static usec_t arg_default_timeout_stop_usec;
ddca0b
+static usec_t arg_default_timeout_abort_usec;
ddca0b
+static bool arg_default_timeout_abort_set;
ddca0b
+static usec_t arg_default_start_limit_interval;
ddca0b
+static unsigned arg_default_start_limit_burst;
ddca0b
+static usec_t arg_runtime_watchdog;
ddca0b
+static usec_t arg_shutdown_watchdog;
ddca0b
+static char *arg_early_core_pattern;
ddca0b
+static char *arg_watchdog_device;
ddca0b
+static char **arg_default_environment;
ddca0b
+static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
ddca0b
+static uint64_t arg_capability_bounding_set;
ddca0b
+static bool arg_no_new_privs;
ddca0b
+static nsec_t arg_timer_slack_nsec;
ddca0b
+static usec_t arg_default_timer_accuracy_usec;
ddca0b
+static Set* arg_syscall_archs;
ddca0b
+static FILE* arg_serialization;
ddca0b
+static int arg_default_cpu_accounting;
ddca0b
+static bool arg_default_io_accounting;
ddca0b
+static bool arg_default_ip_accounting;
ddca0b
+static bool arg_default_blockio_accounting;
ddca0b
+static bool arg_default_memory_accounting;
ddca0b
+static bool arg_default_tasks_accounting;
ddca0b
+static uint64_t arg_default_tasks_max;
ddca0b
+static sd_id128_t arg_machine_id;
ddca0b
+static EmergencyAction arg_cad_burst_action;
ddca0b
+static CPUSet arg_cpu_affinity;
ddca0b
 
ddca0b
 static int parse_configuration(void);
ddca0b
 
ddca0b
@@ -1951,17 +1957,59 @@ static int do_queue_default_job(
ddca0b
         return 0;
ddca0b
 }
ddca0b
 
ddca0b
-static void free_arguments(void) {
ddca0b
-
ddca0b
-        /* Frees all arg_* variables, with the exception of arg_serialization */
ddca0b
-        rlimit_free_all(arg_default_rlimit);
ddca0b
+static void reset_arguments(void) {
ddca0b
+        /* Frees/resets arg_* variables, with a few exceptions commented below. */
ddca0b
 
ddca0b
         arg_default_unit = mfree(arg_default_unit);
ddca0b
+
ddca0b
+        /* arg_system — ignore */
ddca0b
+
ddca0b
+        arg_dump_core = true;
ddca0b
+        arg_crash_chvt = -1;
ddca0b
+        arg_crash_shell = false;
ddca0b
+        arg_crash_reboot = false;
ddca0b
         arg_confirm_spawn = mfree(arg_confirm_spawn);
ddca0b
         arg_join_controllers = strv_free_free(arg_join_controllers);
ddca0b
+        arg_show_status = _SHOW_STATUS_UNSET;
ddca0b
+        arg_switched_root = false;
ddca0b
+        arg_no_pager = false;
ddca0b
+        arg_service_watchdogs = true;
ddca0b
+        arg_default_std_output = EXEC_OUTPUT_JOURNAL;
ddca0b
+        arg_default_std_error = EXEC_OUTPUT_INHERIT;
ddca0b
+        arg_default_restart_usec = DEFAULT_RESTART_USEC;
ddca0b
+        arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
ddca0b
+        arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
ddca0b
+        arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
ddca0b
+        arg_default_timeout_abort_set = false;
ddca0b
+        arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
ddca0b
+        arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
ddca0b
+        arg_runtime_watchdog = 0;
ddca0b
+        arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
ddca0b
+        arg_early_core_pattern = NULL;
ddca0b
+        arg_watchdog_device = NULL;
ddca0b
+
ddca0b
         arg_default_environment = strv_free(arg_default_environment);
ddca0b
+        rlimit_free_all(arg_default_rlimit);
ddca0b
+
ddca0b
+        arg_capability_bounding_set = CAP_ALL;
ddca0b
+        arg_no_new_privs = false;
ddca0b
+        arg_timer_slack_nsec = NSEC_INFINITY;
ddca0b
+        arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
ddca0b
+
ddca0b
         arg_syscall_archs = set_free(arg_syscall_archs);
ddca0b
 
ddca0b
+        /* arg_serialization — ignore */
ddca0b
+
ddca0b
+        arg_default_cpu_accounting = -1;
ddca0b
+        arg_default_io_accounting = false;
ddca0b
+        arg_default_ip_accounting = false;
ddca0b
+        arg_default_blockio_accounting = false;
ddca0b
+        arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
ddca0b
+        arg_default_tasks_accounting = true;
ddca0b
+        arg_default_tasks_max = UINT64_MAX;
ddca0b
+        arg_machine_id = (sd_id128_t) {};
ddca0b
+        arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
ddca0b
+
ddca0b
         cpu_set_reset(&arg_cpu_affinity);
ddca0b
 }
ddca0b
 
ddca0b
@@ -1970,6 +2018,9 @@ static int parse_configuration(void) {
ddca0b
 
ddca0b
         arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
ddca0b
 
ddca0b
+        /* Assign configuration defaults */
ddca0b
+        reset_arguments();
ddca0b
+
ddca0b
         r = parse_config_file();
ddca0b
         if (r < 0)
ddca0b
                 log_warning_errno(r, "Failed to parse config file, ignoring: %m");
ddca0b
@@ -2460,7 +2511,7 @@ finish:
ddca0b
                 m = manager_free(m);
ddca0b
         }
ddca0b
 
ddca0b
-        free_arguments();
ddca0b
+        reset_arguments();
ddca0b
         mac_selinux_finish();
ddca0b
 
ddca0b
         if (reexecute)