]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/main.c
Add config and kernel commandline option to use short identifiers
[thirdparty/systemd.git] / src / core / main.c
index e34da119846cbcb8a6f07bab14cf1163033be7cc..75c488795e47d8d9a25120a56cf31263dc27b2b6 100644 (file)
@@ -96,48 +96,56 @@ static enum {
         ACTION_DUMP_CONFIGURATION_ITEMS,
         ACTION_DUMP_BUS_PROPERTIES,
 } arg_action = ACTION_RUN;
-static char *arg_default_unit = NULL;
-static bool arg_system = false;
-static bool arg_dump_core = true;
-static int arg_crash_chvt = -1;
-static bool arg_crash_shell = false;
-static bool arg_crash_reboot = false;
-static char *arg_confirm_spawn = NULL;
-static ShowStatus arg_show_status = _SHOW_STATUS_INVALID;
-static bool arg_switched_root = false;
-static PagerFlags arg_pager_flags = 0;
-static bool arg_service_watchdogs = true;
-static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
-static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
-static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
-static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
-static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
-static usec_t arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
-static bool arg_default_timeout_abort_set = false;
-static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
-static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
-static usec_t arg_runtime_watchdog = 0;
-static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
-static char *arg_early_core_pattern = NULL;
-static char *arg_watchdog_device = NULL;
-static char **arg_default_environment = NULL;
-static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
-static uint64_t arg_capability_bounding_set = CAP_ALL;
-static bool arg_no_new_privs = false;
-static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
-static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
-static Set* arg_syscall_archs = NULL;
-static FILE* arg_serialization = NULL;
-static int arg_default_cpu_accounting = -1;
-static bool arg_default_io_accounting = false;
-static bool arg_default_ip_accounting = false;
-static bool arg_default_blockio_accounting = false;
-static bool arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
-static bool arg_default_tasks_accounting = true;
-static uint64_t arg_default_tasks_max = UINT64_MAX;
-static sd_id128_t arg_machine_id = {};
-static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
-static OOMPolicy arg_default_oom_policy = OOM_STOP;
+
+/* Those variables are initalized to 0 automatically, so we avoid uninitialized memory access.
+ * Real defaults are assigned in reset_arguments() below. */
+static char *arg_default_unit;
+static bool arg_system;
+static bool arg_dump_core;
+static int arg_crash_chvt;
+static bool arg_crash_shell;
+static bool arg_crash_reboot;
+static char *arg_confirm_spawn;
+static ShowStatus arg_show_status;
+static StatusUnitFormat arg_status_unit_format;
+static bool arg_switched_root;
+static PagerFlags arg_pager_flags;
+static bool arg_service_watchdogs;
+static ExecOutput arg_default_std_output;
+static ExecOutput arg_default_std_error;
+static usec_t arg_default_restart_usec;
+static usec_t arg_default_timeout_start_usec;
+static usec_t arg_default_timeout_stop_usec;
+static usec_t arg_default_timeout_abort_usec;
+static bool arg_default_timeout_abort_set;
+static usec_t arg_default_start_limit_interval;
+static unsigned arg_default_start_limit_burst;
+static usec_t arg_runtime_watchdog;
+static usec_t arg_shutdown_watchdog;
+static char *arg_early_core_pattern;
+static char *arg_watchdog_device;
+static char **arg_default_environment;
+static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
+static uint64_t arg_capability_bounding_set;
+static bool arg_no_new_privs;
+static nsec_t arg_timer_slack_nsec;
+static usec_t arg_default_timer_accuracy_usec;
+static Set* arg_syscall_archs;
+static FILE* arg_serialization;
+static int arg_default_cpu_accounting;
+static bool arg_default_io_accounting;
+static bool arg_default_ip_accounting;
+static bool arg_default_blockio_accounting;
+static bool arg_default_memory_accounting;
+static bool arg_default_tasks_accounting;
+static uint64_t arg_default_tasks_max;
+static sd_id128_t arg_machine_id;
+static EmergencyAction arg_cad_burst_action;
+static OOMPolicy arg_default_oom_policy;
+static CPUSet arg_cpu_affinity;
+static NUMAPolicy arg_numa_policy;
+
+static int parse_configuration(void);
 
 _noreturn_ static void freeze_or_exit_or_reboot(void) {
 
@@ -289,47 +297,6 @@ static int console_setup(void) {
         return 0;
 }
 
-static int parse_crash_chvt(const char *value) {
-        int b;
-
-        if (safe_atoi(value, &arg_crash_chvt) >= 0)
-                return 0;
-
-        b = parse_boolean(value);
-        if (b < 0)
-                return b;
-
-        if (b > 0)
-                arg_crash_chvt = 0; /* switch to where kmsg goes */
-        else
-                arg_crash_chvt = -1; /* turn off switching */
-
-        return 0;
-}
-
-static int parse_confirm_spawn(const char *value, char **console) {
-        char *s;
-        int r;
-
-        r = value ? parse_boolean(value) : 1;
-        if (r == 0) {
-                *console = NULL;
-                return 0;
-        }
-
-        if (r > 0) /* on with default tty */
-                s = strdup("/dev/console");
-        else if (is_path(value)) /* on with fully qualified path */
-                s = strdup(value);
-        else /* on with only a tty file name, not a fully qualified path */
-                s = strjoin("/dev/", value);
-        if (!s)
-                return -ENOMEM;
-
-        *console = s;
-        return 0;
-}
-
 static int set_machine_id(const char *m) {
         sd_id128_t t;
         assert(m);
@@ -385,7 +352,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 if (!value)
                         arg_crash_chvt = 0; /* turn on */
                 else {
-                        r = parse_crash_chvt(value);
+                        r = parse_crash_chvt(value, &arg_crash_chvt);
                         if (r < 0)
                                 log_warning_errno(r, "Failed to parse crash chvt switch %s, ignoring: %m", value);
                 }
@@ -432,6 +399,17 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 } else
                         arg_show_status = SHOW_STATUS_YES;
 
+        } else if (proc_cmdline_key_streq(key, "systemd.status_unit_format")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = status_unit_format_from_string(value);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to parse %s=%s, ignoring: %m", key, value);
+                else
+                        arg_status_unit_format = r;
+
         } else if (proc_cmdline_key_streq(key, "systemd.default_standard_output")) {
 
                 if (proc_cmdline_value_missing(key, value))
@@ -554,216 +532,71 @@ DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level");
 DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target");
 DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" );
 DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location");
-
-static int config_parse_cpu_affinity2(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        _cleanup_cpu_free_ cpu_set_t *c = NULL;
-        int ncpus;
-
-        ncpus = parse_cpu_set_and_warn(rvalue, &c, unit, filename, line, lvalue);
-        if (ncpus < 0)
-                return ncpus;
-
-        if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
-                log_warning_errno(errno, "Failed to set CPU affinity: %m");
-
-        return 0;
-}
-
-static int config_parse_show_status(
-                const char* unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        int k;
-        ShowStatus *b = data;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        k = parse_show_status(rvalue, b);
-        if (k < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse show status setting, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        return 0;
-}
-
-static int config_parse_output_restricted(
-                const char* unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        ExecOutput t, *eo = data;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        t = exec_output_from_string(rvalue);
-        if (t < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse output type, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND)) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file:, append: are not supported as defaults, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        *eo = t;
-        return 0;
-}
-
-static int config_parse_crash_chvt(
-                const char* unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        r = parse_crash_chvt(rvalue);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CrashChangeVT= setting, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        return 0;
-}
-
-static int config_parse_timeout_abort(
-                const char* unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        rvalue += strspn(rvalue, WHITESPACE);
-        if (isempty(rvalue)) {
-                arg_default_timeout_abort_set = false;
-                return 0;
-        }
-
-        r = parse_sec(rvalue, &arg_default_timeout_abort_usec);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DefaultTimeoutAbortSec= setting, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        arg_default_timeout_abort_set = true;
-        return 0;
-}
+DEFINE_SETTER(config_parse_status_unit_format, status_unit_format_from_string, "value");
 
 static int parse_config_file(void) {
 
         const ConfigTableItem items[] = {
-                { "Manager", "LogLevel",                  config_parse_level2,           0, NULL                                   },
-                { "Manager", "LogTarget",                 config_parse_target,           0, NULL                                   },
-                { "Manager", "LogColor",                  config_parse_color,            0, NULL                                   },
-                { "Manager", "LogLocation",               config_parse_location,         0, NULL                                   },
-                { "Manager", "DumpCore",                  config_parse_bool,             0, &arg_dump_core                         },
-                { "Manager", "CrashChVT", /* legacy */    config_parse_crash_chvt,       0, NULL                                   },
-                { "Manager", "CrashChangeVT",             config_parse_crash_chvt,       0, NULL                                   },
-                { "Manager", "CrashShell",                config_parse_bool,             0, &arg_crash_shell                       },
-                { "Manager", "CrashReboot",               config_parse_bool,             0, &arg_crash_reboot                      },
-                { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },
-                { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, NULL                                   },
-                { "Manager", "JoinControllers",           config_parse_warn_compat,      DISABLED_CONFIGURATION, NULL              },
-                { "Manager", "RuntimeWatchdogSec",        config_parse_sec,              0, &arg_runtime_watchdog                  },
-                { "Manager", "ShutdownWatchdogSec",       config_parse_sec,              0, &arg_shutdown_watchdog                 },
-                { "Manager", "WatchdogDevice",            config_parse_path,             0, &arg_watchdog_device                   },
-                { "Manager", "CapabilityBoundingSet",     config_parse_capability_set,   0, &arg_capability_bounding_set           },
-                { "Manager", "NoNewPrivileges",           config_parse_bool,             0, &arg_no_new_privs                      },
+                { "Manager", "LogLevel",                     config_parse_level2,             0, NULL                                   },
+                { "Manager", "LogTarget",                    config_parse_target,             0, NULL                                   },
+                { "Manager", "LogColor",                     config_parse_color,              0, NULL                                   },
+                { "Manager", "LogLocation",                  config_parse_location,           0, NULL                                   },
+                { "Manager", "DumpCore",                     config_parse_bool,               0, &arg_dump_core                         },
+                { "Manager", "CrashChVT", /* legacy */       config_parse_crash_chvt,         0, &arg_crash_chvt                        },
+                { "Manager", "CrashChangeVT",                config_parse_crash_chvt,         0, &arg_crash_chvt                        },
+                { "Manager", "CrashShell",                   config_parse_bool,               0, &arg_crash_shell                       },
+                { "Manager", "CrashReboot",                  config_parse_bool,               0, &arg_crash_reboot                      },
+                { "Manager", "ShowStatus",                   config_parse_show_status,        0, &arg_show_status                       },
+                { "Manager", "StatusUnitFormat",             config_parse_status_unit_format, 0, &arg_status_unit_format                },
+                { "Manager", "CPUAffinity",                  config_parse_cpu_affinity2,      0, &arg_cpu_affinity                      },
+                { "Manager", "NUMAPolicy",                   config_parse_numa_policy,        0, &arg_numa_policy.type                  },
+                { "Manager", "NUMAMask",                     config_parse_numa_mask,          0, &arg_numa_policy                       },
+                { "Manager", "JoinControllers",              config_parse_warn_compat,        DISABLED_CONFIGURATION, NULL              },
+                { "Manager", "RuntimeWatchdogSec",           config_parse_sec,                0, &arg_runtime_watchdog                  },
+                { "Manager", "ShutdownWatchdogSec",          config_parse_sec,                0, &arg_shutdown_watchdog                 },
+                { "Manager", "WatchdogDevice",               config_parse_path,               0, &arg_watchdog_device                   },
+                { "Manager", "CapabilityBoundingSet",        config_parse_capability_set,     0, &arg_capability_bounding_set           },
+                { "Manager", "NoNewPrivileges",              config_parse_bool,               0, &arg_no_new_privs                      },
 #if HAVE_SECCOMP
-                { "Manager", "SystemCallArchitectures",   config_parse_syscall_archs,    0, &arg_syscall_archs                     },
+                { "Manager", "SystemCallArchitectures",      config_parse_syscall_archs,      0, &arg_syscall_archs                     },
 #endif
-                { "Manager", "TimerSlackNSec",            config_parse_nsec,             0, &arg_timer_slack_nsec                  },
-                { "Manager", "DefaultTimerAccuracySec",   config_parse_sec,              0, &arg_default_timer_accuracy_usec       },
-                { "Manager", "DefaultStandardOutput",     config_parse_output_restricted,0, &arg_default_std_output                },
-                { "Manager", "DefaultStandardError",      config_parse_output_restricted,0, &arg_default_std_error                 },
-                { "Manager", "DefaultTimeoutStartSec",    config_parse_sec,              0, &arg_default_timeout_start_usec        },
-                { "Manager", "DefaultTimeoutStopSec",     config_parse_sec,              0, &arg_default_timeout_stop_usec         },
-                { "Manager", "DefaultTimeoutAbortSec",    config_parse_timeout_abort,    0, NULL                                   },
-                { "Manager", "DefaultRestartSec",         config_parse_sec,              0, &arg_default_restart_usec              },
-                { "Manager", "DefaultStartLimitInterval", config_parse_sec,              0, &arg_default_start_limit_interval      }, /* obsolete alias */
-                { "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", "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           },
-                { "Manager", "DefaultLimitSTACK",         config_parse_rlimit,           RLIMIT_STACK, arg_default_rlimit          },
-                { "Manager", "DefaultLimitCORE",          config_parse_rlimit,           RLIMIT_CORE, arg_default_rlimit           },
-                { "Manager", "DefaultLimitRSS",           config_parse_rlimit,           RLIMIT_RSS, arg_default_rlimit            },
-                { "Manager", "DefaultLimitNOFILE",        config_parse_rlimit,           RLIMIT_NOFILE, arg_default_rlimit         },
-                { "Manager", "DefaultLimitAS",            config_parse_rlimit,           RLIMIT_AS, arg_default_rlimit             },
-                { "Manager", "DefaultLimitNPROC",         config_parse_rlimit,           RLIMIT_NPROC, arg_default_rlimit          },
-                { "Manager", "DefaultLimitMEMLOCK",       config_parse_rlimit,           RLIMIT_MEMLOCK, arg_default_rlimit        },
-                { "Manager", "DefaultLimitLOCKS",         config_parse_rlimit,           RLIMIT_LOCKS, arg_default_rlimit          },
-                { "Manager", "DefaultLimitSIGPENDING",    config_parse_rlimit,           RLIMIT_SIGPENDING, arg_default_rlimit     },
-                { "Manager", "DefaultLimitMSGQUEUE",      config_parse_rlimit,           RLIMIT_MSGQUEUE, arg_default_rlimit       },
-                { "Manager", "DefaultLimitNICE",          config_parse_rlimit,           RLIMIT_NICE, arg_default_rlimit           },
-                { "Manager", "DefaultLimitRTPRIO",        config_parse_rlimit,           RLIMIT_RTPRIO, arg_default_rlimit         },
-                { "Manager", "DefaultLimitRTTIME",        config_parse_rlimit,           RLIMIT_RTTIME, arg_default_rlimit         },
-                { "Manager", "DefaultCPUAccounting",      config_parse_tristate,         0, &arg_default_cpu_accounting            },
-                { "Manager", "DefaultIOAccounting",       config_parse_bool,             0, &arg_default_io_accounting             },
-                { "Manager", "DefaultIPAccounting",       config_parse_bool,             0, &arg_default_ip_accounting             },
-                { "Manager", "DefaultBlockIOAccounting",  config_parse_bool,             0, &arg_default_blockio_accounting        },
-                { "Manager", "DefaultMemoryAccounting",   config_parse_bool,             0, &arg_default_memory_accounting         },
-                { "Manager", "DefaultTasksAccounting",    config_parse_bool,             0, &arg_default_tasks_accounting          },
-                { "Manager", "DefaultTasksMax",           config_parse_tasks_max,        0, &arg_default_tasks_max                 },
-                { "Manager", "CtrlAltDelBurstAction",     config_parse_emergency_action, 0, &arg_cad_burst_action                  },
-                { "Manager", "DefaultOOMPolicy",          config_parse_oom_policy,       0, &arg_default_oom_policy                },
+                { "Manager", "TimerSlackNSec",               config_parse_nsec,               0, &arg_timer_slack_nsec                  },
+                { "Manager", "DefaultTimerAccuracySec",      config_parse_sec,                0, &arg_default_timer_accuracy_usec       },
+                { "Manager", "DefaultStandardOutput",        config_parse_output_restricted,  0, &arg_default_std_output                },
+                { "Manager", "DefaultStandardError",         config_parse_output_restricted,  0, &arg_default_std_error                 },
+                { "Manager", "DefaultTimeoutStartSec",       config_parse_sec,                0, &arg_default_timeout_start_usec        },
+                { "Manager", "DefaultTimeoutStopSec",        config_parse_sec,                0, &arg_default_timeout_stop_usec         },
+                { "Manager", "DefaultTimeoutAbortSec",       config_parse_timeout_abort,      0, &arg_default_timeout_abort_set         },
+                { "Manager", "DefaultRestartSec",            config_parse_sec,                0, &arg_default_restart_usec              },
+                { "Manager", "DefaultStartLimitInterval",    config_parse_sec,                0, &arg_default_start_limit_interval      }, /* obsolete alias */
+                { "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", "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           },
+                { "Manager", "DefaultLimitSTACK",            config_parse_rlimit,             RLIMIT_STACK, arg_default_rlimit          },
+                { "Manager", "DefaultLimitCORE",             config_parse_rlimit,             RLIMIT_CORE, arg_default_rlimit           },
+                { "Manager", "DefaultLimitRSS",              config_parse_rlimit,             RLIMIT_RSS, arg_default_rlimit            },
+                { "Manager", "DefaultLimitNOFILE",           config_parse_rlimit,             RLIMIT_NOFILE, arg_default_rlimit         },
+                { "Manager", "DefaultLimitAS",               config_parse_rlimit,             RLIMIT_AS, arg_default_rlimit             },
+                { "Manager", "DefaultLimitNPROC",            config_parse_rlimit,             RLIMIT_NPROC, arg_default_rlimit          },
+                { "Manager", "DefaultLimitMEMLOCK",          config_parse_rlimit,             RLIMIT_MEMLOCK, arg_default_rlimit        },
+                { "Manager", "DefaultLimitLOCKS",            config_parse_rlimit,             RLIMIT_LOCKS, arg_default_rlimit          },
+                { "Manager", "DefaultLimitSIGPENDING",       config_parse_rlimit,             RLIMIT_SIGPENDING, arg_default_rlimit     },
+                { "Manager", "DefaultLimitMSGQUEUE",         config_parse_rlimit,             RLIMIT_MSGQUEUE, arg_default_rlimit       },
+                { "Manager", "DefaultLimitNICE",             config_parse_rlimit,             RLIMIT_NICE, arg_default_rlimit           },
+                { "Manager", "DefaultLimitRTPRIO",           config_parse_rlimit,             RLIMIT_RTPRIO, arg_default_rlimit         },
+                { "Manager", "DefaultLimitRTTIME",           config_parse_rlimit,             RLIMIT_RTTIME, arg_default_rlimit         },
+                { "Manager", "DefaultCPUAccounting",         config_parse_tristate,           0, &arg_default_cpu_accounting            },
+                { "Manager", "DefaultIOAccounting",          config_parse_bool,               0, &arg_default_io_accounting             },
+                { "Manager", "DefaultIPAccounting",          config_parse_bool,               0, &arg_default_ip_accounting             },
+                { "Manager", "DefaultBlockIOAccounting",     config_parse_bool,               0, &arg_default_blockio_accounting        },
+                { "Manager", "DefaultMemoryAccounting",      config_parse_bool,               0, &arg_default_memory_accounting         },
+                { "Manager", "DefaultTasksAccounting",       config_parse_bool,               0, &arg_default_tasks_accounting          },
+                { "Manager", "DefaultTasksMax",              config_parse_tasks_max,          0, &arg_default_tasks_max                 },
+                { "Manager", "CtrlAltDelBurstAction",        config_parse_emergency_action,   0, &arg_cad_burst_action                  },
+                { "Manager", "DefaultOOMPolicy",             config_parse_oom_policy,         0, &arg_default_oom_policy                },
                 {}
         };
 
@@ -843,6 +676,7 @@ static void set_manager_settings(Manager *m) {
         m->cad_burst_action = arg_cad_burst_action;
 
         manager_set_show_status(m, arg_show_status);
+        m->status_unit_format = arg_status_unit_format;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -1015,7 +849,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_CRASH_CHVT:
-                        r = parse_crash_chvt(optarg);
+                        r = parse_crash_chvt(optarg, &arg_crash_chvt);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to parse crash virtual terminal index: \"%s\": %m",
                                                        optarg);
@@ -1155,13 +989,13 @@ static int help(void) {
                "Starts up and maintains the system or user services.\n\n"
                "  -h --help                      Show this help\n"
                "     --version                   Show version\n"
-               "     --test                      Determine startup sequence, dump it and exit\n"
+               "     --test                      Determine initial transaction, dump it and exit\n"
+               "     --system                    In combination with --test: operate as system service manager\n"
+               "     --user                      In combination with --test: operate as per-user service manager\n"
                "     --no-pager                  Do not pipe output into a pager\n"
                "     --dump-configuration-items  Dump understood unit configuration items\n"
                "     --dump-bus-properties       Dump exposed bus properties\n"
                "     --unit=UNIT                 Set default unit\n"
-               "     --system                    Run a system instance, even if PID != 1\n"
-               "     --user                      Run a user instance\n"
                "     --dump-core[=BOOL]          Dump core on crash\n"
                "     --crash-vt=NR               Change to specified VT on crash\n"
                "     --crash-reboot[=BOOL]       Reboot on crash\n"
@@ -1243,9 +1077,9 @@ static void bump_file_max_and_nr_open(void) {
 #endif
 
 #if BUMP_PROC_SYS_FS_FILE_MAX
-        /* I so wanted to use STRINGIFY(ULONG_MAX) here, but alas we can't as glibc/gcc define that as
-         * "(0x7fffffffffffffffL * 2UL + 1UL)". Seriously. ðŸ˜¢ */
-        if (asprintf(&t, "%lu\n", ULONG_MAX) < 0) {
+        /* The maximum the kernel allows for this since 5.2 is LONG_MAX, use that. (Previously thing where
+         * different but the operation would fail silently.) */
+        if (asprintf(&t, "%li\n", LONG_MAX) < 0) {
                 log_oom();
                 return;
         }
@@ -1546,6 +1380,11 @@ static int fixup_environment(void) {
         if (setenv("TERM", t, 1) < 0)
                 return -errno;
 
+        /* The kernels sets HOME=/ for init. Let's undo this. */
+        if (path_equal_ptr(getenv("HOME"), "/") &&
+            unsetenv("HOME") < 0)
+                log_warning_errno(errno, "Failed to unset $HOME: %m");
+
         return 0;
 }
 
@@ -1731,6 +1570,42 @@ static void initialize_core_pattern(bool skip_setup) {
                 log_warning_errno(r, "Failed to write '%s' to /proc/sys/kernel/core_pattern, ignoring: %m", arg_early_core_pattern);
 }
 
+static void update_cpu_affinity(bool skip_setup) {
+        _cleanup_free_ char *mask = NULL;
+
+        if (skip_setup || !arg_cpu_affinity.set)
+                return;
+
+        assert(arg_cpu_affinity.allocated > 0);
+
+        mask = cpu_set_to_string(&arg_cpu_affinity);
+        log_debug("Setting CPU affinity to %s.", strnull(mask));
+
+        if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0)
+                log_warning_errno(errno, "Failed to set CPU affinity: %m");
+}
+
+static void update_numa_policy(bool skip_setup) {
+        int r;
+        _cleanup_free_ char *nodes = NULL;
+        const char * policy = NULL;
+
+        if (skip_setup || !mpol_is_valid(numa_policy_get_type(&arg_numa_policy)))
+                return;
+
+        if (DEBUG_LOGGING) {
+                policy = mpol_to_string(numa_policy_get_type(&arg_numa_policy));
+                nodes = cpu_set_to_range_string(&arg_numa_policy.nodes);
+                log_debug("Setting NUMA policy to %s, with nodes %s.", strnull(policy), strnull(nodes));
+        }
+
+        r = apply_numa_policy(&arg_numa_policy);
+        if (r == -EOPNOTSUPP)
+                log_debug_errno(r, "NUMA support not available, ignoring.");
+        else if (r < 0)
+                log_warning_errno(r, "Failed to set NUMA memory policy: %m");
+}
+
 static void do_reexecute(
                 int argc,
                 char *argv[],
@@ -1897,12 +1772,13 @@ static int invoke_main_loop(
                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
 
-                        r = parse_config_file();
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to parse config file, ignoring: %m");
+                        (void) parse_configuration();
 
                         set_manager_defaults(m);
 
+                        update_cpu_affinity(false);
+                        update_numa_policy(false);
+
                         if (saved_log_level >= 0)
                                 manager_override_log_level(m, saved_log_level);
                         if (saved_log_target >= 0)
@@ -2061,6 +1937,9 @@ static int initialize_runtime(
         if (arg_action != ACTION_RUN)
                 return 0;
 
+        update_cpu_affinity(skip_setup);
+        update_numa_policy(skip_setup);
+
         if (arg_system) {
                 /* Make sure we leave a core dump without panicking the kernel. */
                 install_crash_handler();
@@ -2088,7 +1967,7 @@ static int initialize_runtime(
                                 log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device);
                 }
 
-                if (arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
+                if (timestamp_is_set(arg_runtime_watchdog))
                         watchdog_set_timeout(&arg_runtime_watchdog);
         }
 
@@ -2184,29 +2063,75 @@ static int do_queue_default_job(
         return 0;
 }
 
-static void free_arguments(void) {
-
-        /* Frees all arg_* variables, with the exception of arg_serialization */
-        rlimit_free_all(arg_default_rlimit);
+static void reset_arguments(void) {
+        /* Frees/resets arg_* variables, with a few exceptions commented below. */
 
         arg_default_unit = mfree(arg_default_unit);
+
+        /* arg_system â€” ignore */
+
+        arg_dump_core = true;
+        arg_crash_chvt = -1;
+        arg_crash_shell = false;
+        arg_crash_reboot = false;
         arg_confirm_spawn = mfree(arg_confirm_spawn);
+        arg_show_status = _SHOW_STATUS_INVALID;
+        arg_status_unit_format = STATUS_UNIT_FORMAT_DEFAULT;
+        arg_switched_root = false;
+        arg_pager_flags = 0;
+        arg_service_watchdogs = true;
+        arg_default_std_output = EXEC_OUTPUT_JOURNAL;
+        arg_default_std_error = EXEC_OUTPUT_INHERIT;
+        arg_default_restart_usec = DEFAULT_RESTART_USEC;
+        arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
+        arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+        arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
+        arg_default_timeout_abort_set = false;
+        arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
+        arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
+        arg_runtime_watchdog = 0;
+        arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
+        arg_early_core_pattern = NULL;
+        arg_watchdog_device = NULL;
+
         arg_default_environment = strv_free(arg_default_environment);
+        rlimit_free_all(arg_default_rlimit);
+
+        arg_capability_bounding_set = CAP_ALL;
+        arg_no_new_privs = false;
+        arg_timer_slack_nsec = NSEC_INFINITY;
+        arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
+
         arg_syscall_archs = set_free(arg_syscall_archs);
+
+        /* arg_serialization â€” ignore */
+
+        arg_default_cpu_accounting = -1;
+        arg_default_io_accounting = false;
+        arg_default_ip_accounting = false;
+        arg_default_blockio_accounting = false;
+        arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
+        arg_default_tasks_accounting = true;
+        arg_default_tasks_max = UINT64_MAX;
+        arg_machine_id = (sd_id128_t) {};
+        arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
+        arg_default_oom_policy = OOM_STOP;
+
+        cpu_set_reset(&arg_cpu_affinity);
+        numa_policy_reset(&arg_numa_policy);
 }
 
-static int load_configuration(int argc, char **argv, const char **ret_error_message) {
+static int parse_configuration(void) {
         int r;
 
-        assert(ret_error_message);
-
         arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
 
+        /* Assign configuration defaults */
+        reset_arguments();
+
         r = parse_config_file();
-        if (r < 0) {
-                *ret_error_message = "Failed to parse config file";
-                return r;
-        }
+        if (r < 0)
+                log_warning_errno(r, "Failed to parse config file, ignoring: %m");
 
         if (arg_system) {
                 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
@@ -2217,6 +2142,16 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess
         /* Note that this also parses bits from the kernel command line, including "debug". */
         log_parse_environment();
 
+        return 0;
+}
+
+static int load_configuration(int argc, char **argv, const char **ret_error_message) {
+        int r;
+
+        assert(ret_error_message);
+
+        (void) parse_configuration();
+
         r = parse_argv(argc, argv);
         if (r < 0) {
                 *ret_error_message = "Failed to parse commandline arguments";
@@ -2677,7 +2612,7 @@ finish:
                 m = manager_free(m);
         }
 
-        free_arguments();
+        reset_arguments();
         mac_selinux_finish();
 
         if (reexecute)