#include <sys/reboot.h>
#include <sys/stat.h>
#include <unistd.h>
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
#include <seccomp.h>
#endif
-#ifdef HAVE_VALGRIND_VALGRIND_H
+#if HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>
#endif
#include "cpu-set-util.h"
#include "dbus-manager.h"
#include "def.h"
+#include "emergency-action.h"
#include "env-util.h"
#include "fd-util.h"
#include "fdset.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hostname-setup.h"
#include "ima-setup.h"
#include "mount-setup.h"
#include "pager.h"
#include "parse-util.h"
+#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "raw-clone.h"
#include "rlimit-util.h"
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
#include "seccomp-util.h"
#endif
#include "selinux-setup.h"
#include "user-util.h"
#include "virt.h"
#include "watchdog.h"
-#include "emergency-action.h"
static enum {
ACTION_RUN,
static int arg_crash_chvt = -1;
static bool arg_crash_shell = false;
static bool arg_crash_reboot = false;
-static bool arg_confirm_spawn = false;
+static char *arg_confirm_spawn = NULL;
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
static bool arg_switched_root = false;
static bool arg_no_pager = false;
static FILE* arg_serialization = NULL;
static bool arg_default_cpu_accounting = false;
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 = false;
static bool arg_default_tasks_accounting = true;
struct sigaction sa;
pid_t pid;
- if (getpid() != 1)
+ if (getpid_cached() != 1)
/* Pass this on immediately, if this is not PID 1 */
(void) raise(sig);
else if (!arg_dump_core)
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);
assert(key);
- if (streq(key, "systemd.unit") && value) {
+ if (STR_IN_SET(key, "systemd.unit", "rd.systemd.unit")) {
- if (!in_initrd())
- return free_and_strdup(&arg_default_unit, value);
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
- } else if (streq(key, "rd.systemd.unit") && value) {
-
- if (in_initrd())
- return free_and_strdup(&arg_default_unit, value);
+ if (!unit_name_is_valid(value, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ log_warning("Unit name specified on %s= is not valid, ignoring: %s", key, value);
+ else if (in_initrd() == !!startswith(key, "rd.")) {
+ if (free_and_strdup(&arg_default_unit, value) < 0)
+ return log_oom();
+ }
- } else if (streq(key, "systemd.dump_core") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.dump_core")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse dump core switch %s. Ignoring.", value);
else
arg_dump_core = r;
- } else if (streq(key, "systemd.crash_chvt") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_chvt")) {
- if (parse_crash_chvt(value) < 0)
+ if (!value)
+ arg_crash_chvt = 0; /* turn on */
+ else if (parse_crash_chvt(value) < 0)
log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
- } else if (streq(key, "systemd.crash_shell") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_shell")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse crash shell switch %s. Ignoring.", value);
else
arg_crash_shell = r;
- } else if (streq(key, "systemd.crash_reboot") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_reboot")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse crash reboot switch %s. Ignoring.", value);
else
arg_crash_reboot = r;
- } else if (streq(key, "systemd.confirm_spawn") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.confirm_spawn")) {
+ char *s;
- r = parse_boolean(value);
+ r = parse_confirm_spawn(value, &s);
if (r < 0)
- log_warning("Failed to parse confirm spawn switch %s. Ignoring.", value);
- else
- arg_confirm_spawn = r;
+ log_warning_errno(r, "Failed to parse confirm_spawn switch %s. Ignoring.", value);
+ else {
+ free(arg_confirm_spawn);
+ arg_confirm_spawn = s;
+ }
- } else if (streq(key, "systemd.show_status") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.show_status")) {
- r = parse_show_status(value, &arg_show_status);
- if (r < 0)
- log_warning("Failed to parse show status switch %s. Ignoring.", value);
+ if (value) {
+ r = parse_show_status(value, &arg_show_status);
+ if (r < 0)
+ log_warning("Failed to parse show status switch %s. Ignoring.", value);
+ } else
+ arg_show_status = SHOW_STATUS_YES;
- } else if (streq(key, "systemd.default_standard_output") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.default_standard_output")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = exec_output_from_string(value);
if (r < 0)
else
arg_default_std_output = r;
- } else if (streq(key, "systemd.default_standard_error") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.default_standard_error")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = exec_output_from_string(value);
if (r < 0)
else
arg_default_std_error = r;
- } else if (streq(key, "systemd.setenv") && value) {
+ } else if (streq(key, "systemd.setenv")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (env_assignment_is_valid(value)) {
char **env;
env = strv_env_set(arg_default_environment, value);
- if (env)
- arg_default_environment = env;
- else
- log_warning_errno(ENOMEM, "Setting environment variable '%s' failed, ignoring: %m", value);
+ if (!env)
+ return log_oom();
+
+ arg_default_environment = env;
} else
log_warning("Environment variable name '%s' is not valid. Ignoring.", value);
- } else if (streq(key, "systemd.machine_id") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.machine_id")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = set_machine_id(value);
+ if (r < 0)
+ log_warning("MachineID '%s' is not valid. Ignoring.", value);
+
+ } else if (proc_cmdline_key_streq(key, "systemd.default_timeout_start_sec")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = parse_sec(value, &arg_default_timeout_start_usec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse default start timeout: %s, ignoring.", value);
- r = set_machine_id(value);
- if (r < 0)
- log_warning("MachineID '%s' is not valid. Ignoring.", value);
+ if (arg_default_timeout_start_usec <= 0)
+ arg_default_timeout_start_usec = USEC_INFINITY;
} else if (streq(key, "quiet") && !value) {
target = runlevel_to_target(key);
if (target)
return free_and_strdup(&arg_default_unit, target);
-
- } else if (streq(key, "systemd.default_timeout_start_sec") && value) {
-
- r = parse_sec(value, &arg_default_timeout_start_usec);
- if (r < 0)
- log_warning_errno(r, "Failed to parse default start timeout: %s, ignoring.", value);
-
- if (arg_default_timeout_start_usec <= 0)
- arg_default_timeout_start_usec = USEC_INFINITY;
}
return 0;
return ncpus;
if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
- log_warning("Failed to set CPU affinity: %m");
+ log_warning_errno(errno, "Failed to set CPU affinity: %m");
return 0;
}
char **l;
int r;
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES);
+ r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
return r;
{ "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
{ "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
{ "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set },
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
{ "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
#endif
{ "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
{ "Manager", "DefaultLimitRTTIME", config_parse_limit, RLIMIT_RTTIME, arg_default_rlimit },
{ "Manager", "DefaultCPUAccounting", config_parse_bool, 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 },
m->default_start_limit_burst = arg_default_start_limit_burst;
m->default_cpu_accounting = arg_default_cpu_accounting;
m->default_io_accounting = arg_default_io_accounting;
+ m->default_ip_accounting = arg_default_ip_accounting;
m->default_blockio_accounting = arg_default_blockio_accounting;
m->default_memory_accounting = arg_default_memory_accounting;
m->default_tasks_accounting = arg_default_tasks_accounting;
assert(argc >= 1);
assert(argv);
- if (getpid() == 1)
+ if (getpid_cached() == 1)
opterr = 0;
while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
break;
case ARG_UNIT:
-
r = free_and_strdup(&arg_default_unit, optarg);
if (r < 0)
return log_error_errno(r, "Failed to set default unit %s: %m", optarg);
break;
case ARG_CONFIRM_SPAWN:
- r = optarg ? parse_boolean(optarg) : 1;
- if (r < 0) {
- log_error("Failed to parse confirm spawn boolean %s.", optarg);
- return r;
- }
- arg_confirm_spawn = r;
+ arg_confirm_spawn = mfree(arg_confirm_spawn);
+
+ r = parse_confirm_spawn(optarg, &arg_confirm_spawn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse confirm spawn option: %m");
break;
case ARG_SHOW_STATUS:
* parse_proc_cmdline_word() or ignore. */
case '?':
- if (getpid() != 1)
+ if (getpid_cached() != 1)
return -EINVAL;
else
return 0;
assert_not_reached("Unhandled option code.");
}
- if (optind < argc && getpid() != 1) {
+ if (optind < argc && getpid_cached() != 1) {
/* Hmm, when we aren't run as init system
* let's complain about excess arguments */
printf("%s [OPTIONS...]\n\n"
"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"
" --no-pager Do not pipe output into a pager\n"
" --dump-configuration-items Dump understood unit configuration items\n"
static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
struct rlimit nl;
int r;
+ int min_max;
+ _cleanup_free_ char *nr_open = NULL;
assert(saved_rlimit);
arg_default_rlimit[RLIMIT_NOFILE] = rl;
}
+ /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
+ r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
+ if (r == 0)
+ r = safe_atoi(nr_open, &min_max);
+ /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
+ if (r < 0)
+ min_max = 1024 * 1024;
+
/* Bump up the resource limit for ourselves substantially */
- nl.rlim_cur = nl.rlim_max = 64*1024;
+ nl.rlim_cur = nl.rlim_max = min_max;
r = setrlimit_closest(RLIMIT_NOFILE, &nl);
if (r < 0)
return log_warning_errno(r, "Setting RLIMIT_NOFILE failed, ignoring: %m");
return 0;
}
+static int bump_rlimit_memlock(struct rlimit *saved_rlimit) {
+ int r;
+
+ assert(saved_rlimit);
+ assert(getuid() == 0);
+
+ /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even though we have CAP_IPC_LOCK which
+ * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's
+ * bump the value high enough for the root user. */
+
+ if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit) < 0)
+ return log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m");
+
+ r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL));
+ if (r < 0)
+ return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m");
+
+ return 0;
+}
+
static void test_usr(void) {
/* Check that /usr is not a separate fs */
}
static int enforce_syscall_archs(Set *archs) {
-#ifdef HAVE_SECCOMP
- scmp_filter_ctx *seccomp;
- Iterator i;
- void *id;
+#if HAVE_SECCOMP
int r;
if (!is_seccomp_available())
return 0;
- seccomp = seccomp_init(SCMP_ACT_ALLOW);
- if (!seccomp)
- return log_oom();
-
- SET_FOREACH(id, arg_syscall_archs, i) {
- r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
- if (r == -EEXIST)
- continue;
- if (r < 0) {
- log_error_errno(r, "Failed to add architecture to seccomp: %m");
- goto finish;
- }
- }
-
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0) {
- log_error_errno(r, "Failed to unset NO_NEW_PRIVS: %m");
- goto finish;
- }
-
- r = seccomp_load(seccomp);
+ r = seccomp_restrict_archs(arg_syscall_archs);
if (r < 0)
- log_error_errno(r, "Failed to add install architecture seccomp: %m");
-
-finish:
- seccomp_release(seccomp);
- return r;
-#else
- return 0;
+ return log_error_errno(r, "Failed to enforce system call architecture restrication: %m");
#endif
+ return 0;
}
static int status_welcome(void) {
* However if TERM was configured through the kernel
* command line then leave it alone. */
- r = get_proc_cmdline_key("TERM=", &term);
+ r = proc_cmdline_get_key("TERM", 0, &term);
if (r < 0)
return r;
-
if (r == 0) {
term = strdup(default_term_for_tty("/dev/console"));
if (!term)
bool queue_default_job = false;
bool empty_etc = false;
char *switch_root_dir = NULL, *switch_root_init = NULL;
- struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0);
+ struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1);
const char *error_message = NULL;
-#ifdef HAVE_SYSV_COMPAT
- if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
+#if HAVE_SYSV_COMPAT
+ if (getpid_cached() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatibility support for SysV, where
* calling init as a user is identical to telinit. */
called 'systemd'. That is confusing, hence let's call us
systemd right-away. */
program_invocation_short_name = systemd;
- prctl(PR_SET_NAME, systemd);
+ (void) prctl(PR_SET_NAME, systemd);
saved_argv = argv;
saved_argc = argc;
log_set_upgrade_syslog_to_journal(true);
- /* Disable the umask logic */
- if (getpid() == 1)
+ if (getpid_cached() == 1) {
+ /* Disable the umask logic */
umask(0);
- if (getpid() == 1 && detect_container() <= 0) {
+ /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
+ * important so that we never end up logging to any foreign stderr, for example if we have to log in a
+ * child process right before execve()'ing the actual binary, at a point in time where socket
+ * activation stderr/stdout area already set up. */
+ log_set_always_reopen_console(true);
+ }
+
+ if (getpid_cached() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
arg_system = true;
if (!skip_setup) {
r = mount_setup_early();
if (r < 0) {
- error_message = "Failed to early mount API filesystems";
+ error_message = "Failed to mount early API filesystems";
goto finish;
}
+
dual_timestamp_get(&security_start_timestamp);
if (mac_selinux_setup(&loaded_policy) < 0) {
error_message = "Failed to load SELinux policy";
* might redirect output elsewhere. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
- } else if (getpid() == 1) {
+ } else if (getpid_cached() == 1) {
/* Running inside a container, as PID 1 */
arg_system = true;
log_set_target(LOG_TARGET_CONSOLE);
log_close_console(); /* force reopen of /dev/console */
log_open();
- /* For the later on, see above... */
+ /* For later on, see above... */
log_set_target(LOG_TARGET_JOURNAL);
/* clear the kernel timestamp,
kernel_timestamp = DUAL_TIMESTAMP_NULL;
}
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
/* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
* will process core dumps for system services by default. */
if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
/* Mount /proc, /sys and friends, so that /proc/cmdline and
* /proc/$PID/fd is available. */
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
- /* Load the kernel modules early, so that we kdbus.ko is loaded before kdbusfs shall be mounted */
+ /* Load the kernel modules early. */
if (!skip_setup)
kmod_setup();
}
if (arg_system) {
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
}
log_close();
/* Remember open file descriptors for later deserialization */
- r = fdset_new_fill(&fds);
- if (r < 0) {
- log_emergency_errno(r, "Failed to allocate fd set: %m");
- error_message = "Failed to allocate fd set";
- goto finish;
- } else
- fdset_cloexec(fds, true);
+ if (arg_action == ACTION_RUN) {
+ r = fdset_new_fill(&fds);
+ if (r < 0) {
+ log_emergency_errno(r, "Failed to allocate fd set: %m");
+ error_message = "Failed to allocate fd set";
+ goto finish;
+ } else
+ fdset_cloexec(fds, true);
- if (arg_serialization)
- assert_se(fdset_remove(fds, fileno(arg_serialization)) >= 0);
+ if (arg_serialization)
+ assert_se(fdset_remove(fds, fileno(arg_serialization)) >= 0);
- if (arg_system)
- /* Become a session leader if we aren't one yet. */
- setsid();
+ if (arg_system)
+ /* Become a session leader if we aren't one yet. */
+ setsid();
+ }
/* Move out of the way, so that we won't block unmounts */
assert_se(chdir("/") == 0);
* tty. */
release_terminal();
- if (getpid() == 1 && !skip_setup)
+ if (getpid_cached() == 1 && !skip_setup)
console_setup();
}
/* Make sure we leave a core dump without panicing the
* kernel. */
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
install_crash_handler();
r = mount_cgroup_controllers(arg_join_controllers);
arg_action == ACTION_TEST ? " test" : "", getuid(), t);
}
- if (arg_system && !skip_setup) {
- if (arg_show_status > 0)
- status_welcome();
+ if (arg_action == ACTION_RUN) {
+ if (arg_system && !skip_setup) {
+ if (arg_show_status > 0)
+ status_welcome();
- hostname_setup();
- machine_id_setup(NULL, arg_machine_id, NULL);
- loopback_setup();
- bump_unix_max_dgram_qlen();
+ hostname_setup();
+ machine_id_setup(NULL, arg_machine_id, NULL);
+ loopback_setup();
+ bump_unix_max_dgram_qlen();
- test_usr();
- }
+ test_usr();
+ }
- if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
- watchdog_set_timeout(&arg_runtime_watchdog);
+ if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY)
+ watchdog_set_timeout(&arg_runtime_watchdog);
- if (arg_timer_slack_nsec != NSEC_INFINITY)
- if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
- log_error_errno(errno, "Failed to adjust timer slack: %m");
+ if (arg_timer_slack_nsec != NSEC_INFINITY)
+ if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
+ log_error_errno(errno, "Failed to adjust timer slack: %m");
- if (!cap_test_all(arg_capability_bounding_set)) {
- r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
- if (r < 0) {
- log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
- error_message = "Failed to drop capability bounding set of usermode helpers";
- goto finish;
- }
- r = capability_bounding_set_drop(arg_capability_bounding_set, true);
- if (r < 0) {
- log_emergency_errno(r, "Failed to drop capability bounding set: %m");
- error_message = "Failed to drop capability bounding set";
- goto finish;
+ if (arg_system && !cap_test_all(arg_capability_bounding_set)) {
+ r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
+ if (r < 0) {
+ log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
+ error_message = "Failed to drop capability bounding set of usermode helpers";
+ goto finish;
+ }
+ r = capability_bounding_set_drop(arg_capability_bounding_set, true);
+ if (r < 0) {
+ log_emergency_errno(r, "Failed to drop capability bounding set: %m");
+ error_message = "Failed to drop capability bounding set";
+ goto finish;
+ }
}
- }
- if (arg_syscall_archs) {
- r = enforce_syscall_archs(arg_syscall_archs);
- if (r < 0) {
- error_message = "Failed to set syscall architectures";
- goto finish;
+ if (arg_syscall_archs) {
+ r = enforce_syscall_archs(arg_syscall_archs);
+ if (r < 0) {
+ error_message = "Failed to set syscall architectures";
+ goto finish;
+ }
}
- }
-
- if (!arg_system)
- /* Become reaper of our children */
- if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
- log_warning_errno(errno, "Failed to make us a subreaper: %m");
- if (arg_system) {
- (void) bump_rlimit_nofile(&saved_rlimit_nofile);
+ if (!arg_system)
+ /* Become reaper of our children */
+ if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
+ log_warning_errno(errno, "Failed to make us a subreaper: %m");
- if (empty_etc) {
- r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
- if (r < 0)
- log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r, "Failed to populate /etc with preset unit settings, ignoring: %m");
- else
- log_info("Populated /etc with preset unit settings.");
+ if (arg_system) {
+ /* Bump up RLIMIT_NOFILE for systemd itself */
+ (void) bump_rlimit_nofile(&saved_rlimit_nofile);
+ (void) bump_rlimit_memlock(&saved_rlimit_memlock);
}
}
- r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, arg_action == ACTION_TEST, &m);
+ r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+ arg_action == ACTION_TEST ? MANAGER_TEST_FULL : 0,
+ &m);
if (r < 0) {
log_emergency_errno(r, "Failed to allocate manager object: %m");
error_message = "Failed to allocate manager object";
before_startup = now(CLOCK_MONOTONIC);
r = manager_startup(m, arg_serialization, fds);
- if (r < 0)
+ if (r < 0) {
log_error_errno(r, "Failed to fully start up daemon: %m");
+ goto finish;
+ }
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
arg_default_rlimit[j] = mfree(arg_default_rlimit[j]);
arg_default_unit = mfree(arg_default_unit);
+ arg_confirm_spawn = mfree(arg_confirm_spawn);
arg_join_controllers = strv_free_free(arg_join_controllers);
arg_default_environment = strv_free(arg_default_environment);
arg_syscall_archs = set_free(arg_syscall_archs);
* its child processes */
if (saved_rlimit_nofile.rlim_cur > 0)
(void) setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
+ if (saved_rlimit_memlock.rlim_cur != (rlim_t) -1)
+ (void) setrlimit(RLIMIT_MEMLOCK, &saved_rlimit_memlock);
if (switch_root_dir) {
/* Kill all remaining processes from the
arg_serialization = safe_fclose(arg_serialization);
fds = fdset_free(fds);
-#ifdef HAVE_VALGRIND_VALGRIND_H
+#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
* exit(), not on exec(), hence let's do the former not the
* latter here. */
- if (getpid() == 1 && RUNNING_ON_VALGRIND)
+ if (getpid_cached() == 1 && RUNNING_ON_VALGRIND)
return 0;
#endif
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
log_error_errno(errno, "Failed to execute shutdown binary, %s: %m",
- getpid() == 1 ? "freezing" : "quitting");
+ getpid_cached() == 1 ? "freezing" : "quitting");
}
- if (getpid() == 1) {
+ if (getpid_cached() == 1) {
if (error_message)
manager_status_printf(NULL, STATUS_TYPE_EMERGENCY,
ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL,