diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-14 19:48:04 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-14 21:29:27 -0500 |
commit | 6b3d378331fe714c7bf2263eaa9a8b33fc878e7c (patch) | |
tree | 5fca867e0b2cda62c2dc4f1a9a4bd78ab345b158 /src/core | |
parent | ab8864ebc3ac01288729b44f0d5f18fff37defb5 (diff) | |
parent | bafbac4e85a5eefd4b57a5cd0eb61885fb60edc9 (diff) |
Merge pull request #4879 from poettering/systemd
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/dbus-manager.c | 34 | ||||
-rw-r--r-- | src/core/job.c | 2 | ||||
-rw-r--r-- | src/core/main.c | 125 | ||||
-rw-r--r-- | src/core/mount-setup.c | 24 |
4 files changed, 110 insertions, 75 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 9af49dd1bc..9876251438 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -35,6 +35,7 @@ #include "fd-util.h" #include "fileio.h" #include "format-util.h" +#include "fs-util.h" #include "install.h" #include "log.h" #include "path-util.h" @@ -1484,25 +1485,36 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er if (r < 0) return r; - if (path_equal(root, "/") || !path_is_absolute(root)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root); + if (isempty(root)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory may not be the empty string."); + if (!path_is_absolute(root)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root path '%s' is not absolute.", root); + if (path_equal(root, "/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory."); /* Safety check */ if (isempty(init)) { - if (!path_is_os_tree(root)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root); + r = path_is_os_tree(root); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to determine whether root path '%s' contains an OS tree: %m", root); + if (r == 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.", root); } else { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *chased = NULL; if (!path_is_absolute(init)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init); - p = strappend(root, init); - if (!p) - return -ENOMEM; + r = chase_symlinks(init, root, CHASE_PREFIX_ROOT, &chased); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init); + + if (laccess(chased, X_OK) < 0) { + if (errno == EACCES) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Init binary %s is not executable.", init); - if (access(p, X_OK) < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p); + return sd_bus_error_set_errnof(error, r, "Could not check whether init binary %s is executable: %m", init); + } } rt = strdup(root); diff --git a/src/core/job.c b/src/core/job.c index 2ba4c78096..f7c4c59c32 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -645,7 +645,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR [JOB_DEPENDENCY] = "Dependency failed for %s.", [JOB_ASSERT] = "Assertion failed for %s.", [JOB_UNSUPPORTED] = "Starting of %s not supported.", - [JOB_COLLECTED] = "Unecessary job for %s was removed.", + [JOB_COLLECTED] = "Unnecessary job for %s was removed.", }; static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = { [JOB_DONE] = "Stopped %s.", diff --git a/src/core/main.c b/src/core/main.c index 02992c7324..56a81ab94a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -49,6 +49,7 @@ #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" @@ -90,7 +91,6 @@ #include "user-util.h" #include "virt.h" #include "watchdog.h" -#include "emergency-action.h" static enum { ACTION_RUN, @@ -337,60 +337,73 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat assert(key); - if (streq(key, "systemd.unit") && value) { - - if (!in_initrd()) - return free_and_strdup(&arg_default_unit, value); + if (STR_IN_SET(key, "systemd.unit", "rd.systemd.unit")) { - } else if (streq(key, "rd.systemd.unit") && value) { + if (proc_cmdline_value_missing(key, value)) + return 0; - 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) { - - arg_confirm_spawn = mfree(arg_confirm_spawn); + } else if (proc_cmdline_key_streq(key, "systemd.confirm_spawn")) { + char *s; - r = parse_confirm_spawn(value, &arg_confirm_spawn); + r = parse_confirm_spawn(value, &s); if (r < 0) 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 (proc_cmdline_key_streq(key, "systemd.default_standard_output")) { - } else if (streq(key, "systemd.default_standard_output") && value) { + if (proc_cmdline_value_missing(key, value)) + return 0; r = exec_output_from_string(value); if (r < 0) @@ -398,7 +411,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat 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) @@ -406,24 +422,42 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat 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) { @@ -445,15 +479,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat 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; @@ -1341,10 +1366,9 @@ static int fixup_environment(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) @@ -1411,7 +1435,7 @@ int main(int argc, char *argv[]) { 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; @@ -1435,9 +1459,10 @@ int main(int argc, char *argv[]) { 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"; @@ -1513,7 +1538,7 @@ int main(int argc, char *argv[]) { 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, @@ -1590,7 +1615,7 @@ int main(int argc, char *argv[]) { } 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"); } diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 6338067d7e..9c2bf3a0ef 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -360,7 +360,6 @@ int mount_setup(bool loaded_policy) { int r = 0; r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy); - if (r < 0) return r; @@ -391,25 +390,24 @@ int mount_setup(bool loaded_policy) { * udevd. */ dev_setup(NULL, UID_INVALID, GID_INVALID); - /* Mark the root directory as shared in regards to mount - * propagation. The kernel defaults to "private", but we think - * it makes more sense to have a default of "shared" so that - * nspawn and the container tools work out of the box. If - * specific setups need other settings they can reset the - * propagation mode to private if needed. */ + /* Mark the root directory as shared in regards to mount propagation. The kernel defaults to "private", but we + * think it makes more sense to have a default of "shared" so that nspawn and the container tools work out of + * the box. If specific setups need other settings they can reset the propagation mode to private if + * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a + * container manager we assume the container manager knows what it is doing (for example, because it set up + * some directories with different propagation modes). */ if (detect_container() <= 0) if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m"); - /* Create a few directories we always want around, Note that - * sd_booted() checks for /run/systemd/system, so this mkdir - * really needs to stay for good, otherwise software that - * copied sd-daemon.c into their sources will misdetect - * systemd. */ + /* Create a few directories we always want around, Note that sd_booted() checks for /run/systemd/system, so + * this mkdir really needs to stay for good, otherwise software that copied sd-daemon.c into their sources will + * misdetect systemd. */ (void) mkdir_label("/run/systemd", 0755); (void) mkdir_label("/run/systemd/system", 0755); - (void) mkdir_label("/run/systemd/inaccessible", 0000); + /* Set up inaccessible items */ + (void) mkdir_label("/run/systemd/inaccessible", 0000); (void) mknod("/run/systemd/inaccessible/reg", S_IFREG | 0000, 0); (void) mkdir_label("/run/systemd/inaccessible/dir", 0000); (void) mknod("/run/systemd/inaccessible/chr", S_IFCHR | 0000, makedev(0, 0)); |