#include "alloc-util.h"
#include "apparmor-setup.h"
#include "architecture.h"
+#include "argv-util.h"
#if HAVE_LIBBPF
#include "bpf-lsm.h"
#endif
#include "crash-handler.h"
#include "dbus-manager.h"
#include "dbus.h"
-#include "def.h"
+#include "constants.h"
#include "dev-setup.h"
#include "efi-random.h"
#include "efivars.h"
#include "hostname-setup.h"
#include "ima-setup.h"
#include "import-creds.h"
+#include "initrd-util.h"
#include "killall.h"
#include "kmod-setup.h"
#include "limits-util.h"
#include "time-util.h"
#include "umask-util.h"
#include "user-util.h"
-#include "util.h"
#include "virt.h"
#include "watchdog.h"
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 usec_t arg_default_device_timeout_usec;
static bool arg_default_timeout_abort_set;
static usec_t arg_default_start_limit_interval;
static unsigned arg_default_start_limit_burst;
static size_t arg_random_seed_size;
static int arg_default_oom_score_adjust;
static bool arg_default_oom_score_adjust_set;
+static char *arg_default_smack_process_label;
/* A copy of the original environment block */
static char **saved_env = NULL;
{ "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_default_timeout_abort, 0, NULL },
+ { "Manager", "DefaultDeviceTimeoutSec", config_parse_sec, 0, &arg_default_device_timeout_usec },
{ "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", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action },
{ "Manager", "DefaultOOMPolicy", config_parse_oom_policy, 0, &arg_default_oom_policy },
{ "Manager", "DefaultOOMScoreAdjust", config_parse_oom_score_adjust, 0, NULL },
+#if ENABLE_SMACK
+ { "Manager", "DefaultSmackProcessLabel", config_parse_string, 0, &arg_default_smack_process_label },
+#else
+ { "Manager", "DefaultSmackProcessLabel", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL },
+#endif
{}
};
config_item_table_lookup, items,
CONFIG_PARSE_WARN,
NULL,
+ NULL,
NULL);
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use
m->default_timeout_stop_usec = arg_default_timeout_stop_usec;
m->default_timeout_abort_usec = arg_default_timeout_abort_usec;
m->default_timeout_abort_set = arg_default_timeout_abort_set;
+ m->default_device_timeout_usec = arg_default_device_timeout_usec;
m->default_restart_usec = arg_default_restart_usec;
m->default_start_limit_interval = arg_default_start_limit_interval;
m->default_start_limit_burst = arg_default_start_limit_burst;
m->default_oom_score_adjust_set = arg_default_oom_score_adjust_set;
m->default_oom_score_adjust = arg_default_oom_score_adjust;
+ (void) manager_set_default_smack_process_label(m, arg_default_smack_process_label);
+
(void) manager_set_default_rlimits(m, arg_default_rlimit);
(void) manager_default_environment(m);
log_warning("/usr appears to be on its own filesystem and is not already mounted. This is not a supported setup. "
"Some things will probably break (sometimes even silently) in mysterious ways. "
- "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
+ "Consult https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
}
static int enforce_syscall_archs(Set *archs) {
return 0;
}
-static int status_welcome(void) {
- _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
+static int os_release_status(void) {
+ _cleanup_free_ char *pretty_name = NULL, *name = NULL, *version = NULL,
+ *ansi_color = NULL, *support_end = NULL;
int r;
- if (!show_status_on(arg_show_status))
- return 0;
-
r = parse_os_release(NULL,
"PRETTY_NAME", &pretty_name,
- "ANSI_COLOR", &ansi_color);
+ "NAME", &name,
+ "VERSION", &version,
+ "ANSI_COLOR", &ansi_color,
+ "SUPPORT_END", &support_end);
if (r < 0)
- log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to read os-release file, ignoring: %m");
+ return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to read os-release file, ignoring: %m");
- if (log_get_show_color())
- return status_printf(NULL, 0,
- "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
- isempty(ansi_color) ? "1" : ansi_color,
- isempty(pretty_name) ? "Linux" : pretty_name);
- else
- return status_printf(NULL, 0,
- "\nWelcome to %s!\n",
- isempty(pretty_name) ? "Linux" : pretty_name);
+ const char *label = empty_to_null(pretty_name) ?: empty_to_null(name) ?: "Linux";
+
+ if (show_status_on(arg_show_status)) {
+ if (log_get_show_color())
+ status_printf(NULL, 0,
+ "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+ empty_to_null(ansi_color) ?: "1",
+ label);
+ else
+ status_printf(NULL, 0,
+ "\nWelcome to %s!\n",
+ label);
+ }
+
+ if (support_end && os_release_support_ended(support_end, false) > 0)
+ /* pretty_name may include the version already, so we'll print the version only if we
+ * have it and we're not using pretty_name. */
+ status_printf(ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL, 0,
+ "This OS version (%s%s%s) is past its end-of-support date (%s)",
+ label,
+ (pretty_name || !version) ? "" : " version ",
+ (pretty_name || !version) ? "" : version,
+ support_end);
+
+ return 0;
}
static int write_container_id(void) {
/* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
* until the systemd-coredump tool is enabled via sysctl. However it can be changed via the kernel
- * command line later so core dumps can still be generated during early startup and in initramfs. */
+ * command line later so core dumps can still be generated during early startup and in initrd. */
if (!skip_setup)
disable_coredumps();
#endif
continue;
}
- if (startswith(src[i],
- in_initrd() ? "rd.systemd.unit=" : "systemd.unit="))
- continue;
-
- if (runlevel_to_target(src[i]))
- continue;
-
/* Seems we have a good old option. Let's pass it over to the new instance. */
dst[(*dst_index)++] = src[i];
}
args[i++] = argv[j];
assert(i <= args_size);
- /* Re-enable any blocked signals, especially important if we switch from initial ramdisk to init=... */
+ /* Re-enable any blocked signals, especially important if we switch from initrd to init=... */
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
(void) rlimit_nofile_safe();
return objective;
case MANAGER_SWITCH_ROOT:
+ manager_set_switching_root(m, true);
+
if (!m->switch_root_init) {
r = prepare_reexecute(m, &arg_serialization, ret_fds, true);
if (r < 0) {
}
static void log_execution_mode(bool *ret_first_boot) {
+ bool first_boot = false;
+
assert(ret_first_boot);
if (arg_system) {
log_info("Detected architecture %s.", architecture_to_string(uname_architecture()));
- if (in_initrd()) {
- *ret_first_boot = false;
- log_info("Running in initial RAM disk.");
- } else {
+ if (in_initrd())
+ log_info("Running in initrd.");
+ else {
int r;
_cleanup_free_ char *id_text = NULL;
- /* Let's check whether we are in first boot. We use /etc/machine-id as flag file
- * for this: If it is missing or contains the value "uninitialized", this is the
- * first boot. In any other case, it is not. This allows container managers and
- * installers to provision a couple of files already. If the container manager
- * wants to provision the machine ID itself it should pass $container_uuid to PID 1. */
-
- r = read_one_line_file("/etc/machine-id", &id_text);
- if (r < 0 || streq(id_text, "uninitialized")) {
- if (r < 0 && r != -ENOENT)
- log_warning_errno(r, "Unexpected error while reading /etc/machine-id, ignoring: %m");
-
- *ret_first_boot = true;
- log_info("Detected first boot.");
- } else {
- *ret_first_boot = false;
- log_debug("Detected initialized system, this is not the first boot.");
+ /* Let's check whether we are in first boot. First, check if an override was
+ * specified on the kernel commandline. If yes, we honour that. */
+
+ r = proc_cmdline_get_bool("systemd.condition-first-boot", &first_boot);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse systemd.condition-first-boot= kernel commandline argument, ignoring: %m");
+
+ if (r > 0)
+ log_full(first_boot ? LOG_INFO : LOG_DEBUG,
+ "Kernel commandline argument says we are %s first boot.",
+ first_boot ? "in" : "not in");
+ else {
+ /* Second, perform autodetection. We use /etc/machine-id as flag file for
+ * this: If it is missing or contains the value "uninitialized", this is the
+ * first boot. In other cases, it is not. This allows container managers and
+ * installers to provision a couple of files in /etc but still permit the
+ * first-boot initialization to occur. If the container manager wants to
+ * provision the machine ID it should pass $container_uuid to PID 1. */
+
+ r = read_one_line_file("/etc/machine-id", &id_text);
+ if (r < 0 || streq(id_text, "uninitialized")) {
+ if (r < 0 && r != -ENOENT)
+ log_warning_errno(r, "Unexpected error while reading /etc/machine-id, ignoring: %m");
+
+ first_boot = true;
+ log_info("Detected first boot.");
+ } else
+ log_debug("Detected initialized system, this is not the first boot.");
}
}
arg_action == ACTION_TEST ? " test" : "",
getuid(), strna(t), systemd_features);
}
-
- *ret_first_boot = false;
}
+
+ *ret_first_boot = first_boot;
}
static int initialize_runtime(
return r;
}
- status_welcome();
+ (void) os_release_status();
(void) hostname_setup(true);
/* Force transient machine-id on first boot. */
- machine_id_setup(NULL, first_boot, arg_machine_id, NULL);
+ machine_id_setup(NULL, /* force_transient= */ first_boot, arg_machine_id, NULL);
(void) loopback_setup();
bump_unix_max_dgram_qlen();
bump_file_max_and_nr_open();
write_container_id();
}
- if (arg_watchdog_device) {
- r = watchdog_set_device(arg_watchdog_device);
- if (r < 0)
- log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device);
- }
+ r = watchdog_set_device(arg_watchdog_device);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device);
} else {
_cleanup_free_ char *p = NULL;
arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
arg_default_timeout_abort_set = false;
+ arg_default_device_timeout_usec = DEFAULT_TIMEOUT_USEC;
arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
arg_runtime_watchdog = 0;
arg_reboot_watchdog = 10 * USEC_PER_MINUTE;
arg_kexec_watchdog = 0;
arg_pretimeout_watchdog = 0;
- arg_early_core_pattern = NULL;
- arg_watchdog_device = NULL;
+ arg_early_core_pattern = mfree(arg_early_core_pattern);
+ arg_watchdog_device = mfree(arg_watchdog_device);
arg_watchdog_pretimeout_governor = mfree(arg_watchdog_pretimeout_governor);
arg_default_environment = strv_free(arg_default_environment);
arg_clock_usec = 0;
arg_default_oom_score_adjust_set = false;
+ arg_default_smack_process_label = mfree(arg_default_smack_process_label);
}
static void determine_default_oom_score_adjust(void) {
goto finish;
}
- /* The efivarfs is now mounted, let's read the random seed off it */
- (void) efi_take_random_seed();
+ /* The efivarfs is now mounted, let's lock down the system token. */
+ lock_down_efi_variables();
/* Cache command-line options passed from EFI variables */
if (!skip_setup)
} else {
/* Running as user instance */
arg_system = false;
+ log_set_always_reopen_console(true);
log_set_target(LOG_TARGET_AUTO);
log_open();
/* clear the kernel timestamp, because we are not PID 1 */
kernel_timestamp = DUAL_TIMESTAMP_NULL;
+ /* Clear ambient capabilities, so services do not inherit them implicitly. Dropping them does
+ * not affect the permitted and effective sets which are important for the manager itself to
+ * operate. */
+ capability_ambient_set_apply(0, /* also_inherit= */ false);
+
if (mac_selinux_init() < 0) {
error_message = "Failed to initialize SELinux support";
goto finish;
set_manager_defaults(m);
set_manager_settings(m);
manager_set_first_boot(m, first_boot);
+ manager_set_switching_root(m, arg_switched_root);
/* Remember whether we should queue the default job */
queue_default_job = !arg_serialization || arg_switched_root;
/* Cleanup watchdog_device strings for valgrind. We need them
* in become_shutdown() so normally we cannot free them yet. */
watchdog_free_device();
- arg_watchdog_device = mfree(arg_watchdog_device);
reset_arguments();
return retval;
}