X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=8abad6d25728216c69e5ed890e2742f2dce80db1;hp=ad155e13caa6dd45ea13fdb54df764bc50f3d210;hb=8be28fb1e0aa57b2a6ba7736440c9bba54cb86d1;hpb=21bf2ab082b42f03df5b4685df2fddc4d6e0d572 diff --git a/src/core/main.c b/src/core/main.c index ad155e13c..8abad6d25 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -64,7 +64,6 @@ #endif #include "hostname-setup.h" #include "machine-id-setup.h" -#include "locale-setup.h" #include "selinux-setup.h" #include "ima-setup.h" #include "fileio.h" @@ -91,6 +90,9 @@ static bool arg_switched_root = false; static char ***arg_join_controllers = NULL; 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_runtime_watchdog = 0; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; static char **arg_default_environment = NULL; @@ -349,32 +351,21 @@ static int parse_proc_cmdline_word(const char *word) { arg_default_std_error = r; } else if (startswith(word, "systemd.setenv=")) { _cleanup_free_ char *cenv = NULL; - char *eq; - int r; cenv = strdup(word + 15); if (!cenv) return -ENOMEM; - eq = strchr(cenv, '='); - if (!eq) { - if (!env_name_is_valid(cenv)) - log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv); - else { - r = unsetenv(cenv); - if (r < 0) - log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv); - } - } else { - if (!env_assignment_is_valid(cenv)) - log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv); - else { - *eq = 0; - r = setenv(cenv, eq + 1, 1); - if (r < 0) - log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1); - } - } + if (env_assignment_is_valid(cenv)) { + char **env; + + env = strv_env_set(arg_default_environment, cenv); + if (env) + arg_default_environment = env; + else + log_warning("Setting environment variable '%s' failed, ignoring: %m", cenv); + } else + log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv); } else if (startswith(word, "systemd.") || (in_initrd() && startswith(word, "rd.systemd."))) { @@ -413,9 +404,14 @@ static int parse_proc_cmdline_word(const char *word) { } else if (streq(word, "quiet")) arg_show_status = false; - else if (streq(word, "debug")) + else if (streq(word, "debug")) { + /* Log to kmsg, the journal socket will fill up before the + * journal is started and tools running during that time + * will block with every log message for for 60 seconds, + * before they give up. */ log_set_max_level(LOG_DEBUG); - else if (!in_initrd()) { + log_set_target(LOG_TARGET_KMSG); + } else if (!in_initrd()) { unsigned i; /* SysV compatibility */ @@ -643,6 +639,9 @@ static int parse_config_file(void) { { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output }, { "Manager", "DefaultStandardError", config_parse_output, 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", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec }, { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog }, { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, @@ -692,19 +691,14 @@ static int parse_config_file(void) { static int parse_proc_cmdline(void) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - /* Don't read /proc/cmdline if we are in a container, since - * that is only relevant for the host system */ - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word; @@ -742,7 +736,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_SHOW_STATUS, ARG_DESERIALIZE, ARG_SWITCHED_ROOT, - ARG_INTROSPECT, ARG_DEFAULT_STD_OUTPUT, ARG_DEFAULT_STD_ERROR }; @@ -765,7 +758,6 @@ static int parse_argv(int argc, char *argv[]) { { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT }, - { "introspect", optional_argument, NULL, ARG_INTROSPECT }, { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, { NULL, 0, NULL, 0 } @@ -937,27 +929,6 @@ static int parse_argv(int argc, char *argv[]) { arg_switched_root = true; break; - case ARG_INTROSPECT: { - const char * const * i = NULL; - - for (i = bus_interface_table; *i; i += 2) - if (!optarg || streq(i[0], optarg)) { - fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE - "\n", stdout); - fputs(i[1], stdout); - fputs("\n", stdout); - - if (optarg) - break; - } - - if (!i[0] && optarg) - log_error("Unknown interface %s.", optarg); - - arg_action = ACTION_DONE; - break; - } - case 'h': arg_action = ACTION_HELP; break; @@ -1003,11 +974,13 @@ static int parse_argv(int argc, char *argv[]) { * relevant for the container, hence we rely on argv[] * instead. */ - for (a = argv; a < argv + argc; a++) - if ((r = parse_proc_cmdline_word(*a)) < 0) { + for (a = argv; a < argv + argc; a++) { + r = parse_proc_cmdline_word(*a); + if (r < 0) { log_error("Failed on cmdline argument %s: %s", *a, strerror(-r)); return r; } + } } return 0; @@ -1020,7 +993,6 @@ static int help(void) { " -h --help Show this help\n" " --test Determine startup sequence, dump it and exit\n" " --dump-configuration-items Dump understood unit configuration items\n" - " --introspect[=INTERFACE] Extract D-Bus interface data\n" " --unit=UNIT Set default unit\n" " --system Run a system instance, even if PID != 1\n" " --user Run a user instance\n" @@ -1272,6 +1244,10 @@ int main(int argc, char *argv[]) { log_show_color(isatty(STDERR_FILENO) > 0); + /* Disable the umask logic */ + if (getpid() == 1) + umask(0); + if (getpid() == 1 && detect_container(NULL) <= 0) { /* Running outside of a container as PID 1 */ @@ -1429,6 +1405,12 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_running_as == SYSTEMD_USER && + !getenv("XDG_RUNTIME_DIR")) { + log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set."); + goto finish; + } + assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST); /* Close logging fds, in order not to confuse fdset below */ @@ -1445,49 +1427,10 @@ int main(int argc, char *argv[]) { if (serialization) assert_se(fdset_remove(fds, fileno(serialization)) >= 0); - /* Set up PATH unless it is already set */ - setenv("PATH", -#ifdef HAVE_SPLIT_USR - "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", -#else - "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", -#endif - arg_running_as == SYSTEMD_SYSTEM); - - if (arg_running_as == SYSTEMD_SYSTEM) { - /* Unset some environment variables passed in from the - * kernel that don't really make sense for us. */ - unsetenv("HOME"); - unsetenv("TERM"); - - /* When we are invoked by a shell, these might be set, - * but make little sense to pass on */ - unsetenv("PWD"); - unsetenv("SHLVL"); - unsetenv("_"); - - /* When we are invoked by a chroot-like tool such as - * nspawn, these might be set, but make little sense - * to pass on */ - unsetenv("USER"); - unsetenv("LOGNAME"); - - /* We suppress the socket activation env vars, as - * we'll try to match *any* open fd to units if - * possible. */ - unsetenv("LISTEN_FDS"); - unsetenv("LISTEN_PID"); - - /* All other variables are left as is, so that clients - * can still read them via /proc/1/environ */ - + if (arg_running_as == SYSTEMD_SYSTEM) /* Become a session leader if we aren't one yet. */ setsid(); - /* Disable the umask logic */ - umask(0); - } - /* Move out of the way, so that we won't block unmounts */ assert_se(chdir("/") == 0); @@ -1528,8 +1471,6 @@ int main(int argc, char *argv[]) { log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")"); if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { - locale_setup(); - if (arg_show_status || plymouth_running()) status_welcome(); @@ -1553,14 +1494,14 @@ int main(int argc, char *argv[]) { log_error("Failed to adjust timer slack: %m"); if (arg_capability_bounding_set_drop) { - r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); if (r < 0) { - log_error("Failed to drop capability bounding set: %s", strerror(-r)); + log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); goto finish; } - r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); + r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); if (r < 0) { - log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); + log_error("Failed to drop capability bounding set: %s", strerror(-r)); goto finish; } } @@ -1586,6 +1527,9 @@ int main(int argc, char *argv[]) { m->confirm_spawn = arg_confirm_spawn; m->default_std_output = arg_default_std_output; m->default_std_error = arg_default_std_error; + m->default_restart_usec = arg_default_restart_usec; + m->default_timeout_start_usec = arg_default_timeout_start_usec; + m->default_timeout_stop_usec = arg_default_timeout_stop_usec; m->runtime_watchdog = arg_runtime_watchdog; m->shutdown_watchdog = arg_shutdown_watchdog; m->userspace_timestamp = userspace_timestamp; @@ -1595,7 +1539,7 @@ int main(int argc, char *argv[]) { manager_set_default_rlimits(m, arg_default_rlimit); if (arg_default_environment) - manager_set_default_environment(m, arg_default_environment); + manager_environment_add(m, arg_default_environment); manager_set_show_status(m, arg_show_status); @@ -1611,6 +1555,7 @@ int main(int argc, char *argv[]) { /* This will close all file descriptors that were opened, but * not claimed by any unit. */ fdset_free(fds); + fds = NULL; if (serialization) { fclose(serialization); @@ -1825,6 +1770,10 @@ finish: args[i++] = sfd; args[i++] = NULL; + /* do not pass along the environment we inherit from the kernel or initrd */ + if (switch_root_dir) + clearenv(); + assert(i <= args_size); execv(args[0], (char* const*) args); }