X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=b3ee1b9b889960589c7730cccb8687a88e1609d6;hp=feabead96d7567fb8609508c43ed34213e180d93;hb=ca05941b9a6d7855bda2a7cb2cc16bbd3911acdd;hpb=b2103dccb354de3f38c49c14ccb637bdf665e40f diff --git a/src/core/main.c b/src/core/main.c index feabead96..b3ee1b9b8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -61,7 +61,7 @@ #include "capability.h" #include "killall.h" #include "env-util.h" -#include "hwclock.h" +#include "clock-util.h" #include "fileio.h" #include "dbus-manager.h" #include "bus-error.h" @@ -286,7 +286,8 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { } else if (streq(key, "rd.systemd.unit") && value) { - return set_default_unit(value); + if (in_initrd()) + return set_default_unit(value); } else if (streq(key, "systemd.log_target") && value) { @@ -412,11 +413,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { } } else if (streq(key, "quiet") && !value) { + + log_set_max_level(LOG_NOTICE); + if (arg_show_status == _SHOW_STATUS_UNSET) arg_show_status = SHOW_STATUS_AUTO; } else if (streq(key, "debug") && !value) { + log_set_max_level(LOG_DEBUG); + if (detect_container(NULL) > 0) log_set_target(LOG_TARGET_CONSOLE); @@ -1151,19 +1157,25 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { } static void test_mtab(void) { - char *p; - /* Check that /etc/mtab is a symlink */ + static const char ok[] = + "/proc/self/mounts\0" + "/proc/mounts\0" + "../proc/self/mounts\0" + "../proc/mounts\0"; - if (readlink_malloc("/etc/mtab", &p) >= 0) { - bool b; + _cleanup_free_ char *p = NULL; + int r; - b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts"); - free(p); + /* Check that /etc/mtab is a symlink to the right place or + * non-existing. But certainly not a file, or a symlink to + * some weird place... */ - if (b) - return; - } + r = readlink_malloc("/etc/mtab", &p); + if (r == -ENOENT) + return; + if (r >= 0 && nulstr_contains(ok, p)) + return; log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. " "This is not supported anymore. " @@ -1182,21 +1194,6 @@ static void test_usr(void) { "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); } -static void test_cgroups(void) { - - if (access("/proc/cgroups", F_OK) >= 0) - return; - - log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. " - "Systems without control groups are not supported. " - "We will now sleep for 10s, and then continue boot-up. " - "Expect breakage and please do not file bugs. " - "Instead fix your kernel and enable CONFIG_CGROUPS. " - "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information."); - - sleep(10); -} - static int initialize_join_controllers(void) { /* By default, mount "cpu" + "cpuacct" together, and "net_cls" * + "net_prio". We'd like to add "cpuset" to the mix, but @@ -1266,9 +1263,15 @@ static int status_welcome(void) { "PRETTY_NAME", &pretty_name, "ANSI_COLOR", &ansi_color, NULL); + if (r == -ENOENT) { + r = parse_env_file("/usr/lib/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "ANSI_COLOR", &ansi_color, + NULL); + } if (r < 0 && r != -ENOENT) - log_warning("Failed to read /etc/os-release: %s", strerror(-r)); + log_warning("Failed to read os-release file: %s", strerror(-r)); return status_printf(NULL, false, false, "\nWelcome to \x1B[%sm%s\x1B[0m!\n", @@ -1276,6 +1279,16 @@ static int status_welcome(void) { isempty(pretty_name) ? "Linux" : pretty_name); } +static int write_container_id(void) { + const char *c; + + c = getenv("container"); + if (isempty(c)) + return 0; + + return write_string_file("/run/systemd/container", c); +} + int main(int argc, char *argv[]) { Manager *m = NULL; int r, retval = EXIT_FAILURE; @@ -1295,6 +1308,7 @@ int main(int argc, char *argv[]) { bool loaded_policy = false; bool arm_reboot_watchdog = false; bool queue_default_job = false; + bool empty_etc = false; char *switch_root_dir = NULL, *switch_root_init = NULL; static struct rlimit saved_rlimit_nofile = { 0, 0 }; @@ -1367,11 +1381,11 @@ int main(int argc, char *argv[]) { goto finish; if (!skip_setup) { - if (hwclock_is_localtime() > 0) { + if (clock_is_localtime() > 0) { int min; /* The first-time call to settimeofday() does a time warp in the kernel */ - r = hwclock_set_timezone(&min); + r = clock_set_timezone(&min); if (r < 0) log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); else @@ -1385,10 +1399,10 @@ int main(int argc, char *argv[]) { * that way. In such case, we need to delay the time-warp or the sealing * until we reach the real system. */ - hwclock_reset_timezone(); + clock_reset_timezone(); /* Tell the kernel our timezone */ - r = hwclock_set_timezone(NULL); + r = clock_set_timezone(NULL); if (r < 0) log_error("Failed to set the kernel's timezone, ignoring: %s", strerror(-r)); } @@ -1559,11 +1573,16 @@ int main(int argc, char *argv[]) { if (virtualization) log_info("Detected virtualization '%s'.", virtualization); + write_container_id(); + log_info("Detected architecture '%s'.", architecture_to_string(uname_architecture())); if (in_initrd()) log_info("Running in initial RAM disk."); + empty_etc = dir_is_empty("/etc") > 0; + if (empty_etc) + log_info("Running with unpopulated /etc."); } else { _cleanup_free_ char *t = uid_to_name(getuid()); log_debug(PACKAGE_STRING " running in user mode for user "PID_FMT"/%s. (" SYSTEMD_FEATURES ")", @@ -1575,16 +1594,14 @@ int main(int argc, char *argv[]) { status_welcome(); #ifdef HAVE_KMOD - if (detect_container(NULL) <= 0) - kmod_setup(); + kmod_setup(); #endif hostname_setup(); - machine_id_setup(""); + machine_id_setup(NULL); loopback_setup(); test_mtab(); test_usr(); - test_cgroups(); } if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0) @@ -1622,9 +1639,18 @@ int main(int argc, char *argv[]) { } } - if (arg_running_as == SYSTEMD_SYSTEM) + if (arg_running_as == SYSTEMD_SYSTEM) { bump_rlimit_nofile(&saved_rlimit_nofile); + if (empty_etc) { + r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, NULL, UNIT_FILE_PRESET_FULL, false, NULL, 0); + if (r < 0) + log_warning("Failed to populate /etc with preset unit settings, ignoring: %s", strerror(-r)); + else + log_info("Populated /etc with preset unit settings."); + } + } + r = manager_new(arg_running_as, &m); if (r < 0) { log_error("Failed to allocate manager object: %s", strerror(-r)); @@ -1835,6 +1861,7 @@ finish: if (reexecute) { const char **args; unsigned i, args_size; + sigset_t ss, o_ss; /* Close and disarm the watchdog, so that the new * instance can reinitialize it, but doesn't get @@ -1918,6 +1945,11 @@ finish: args[i++] = NULL; assert(i <= args_size); + /* reenable any blocked signals, especially important + * if we switch from initial ramdisk to init=... */ + sigemptyset(&ss); + sigprocmask(SIG_SETMASK, &ss, &o_ss); + if (switch_root_init) { args[0] = switch_root_init; execv(args[0], (char* const*) args); @@ -1936,6 +1968,8 @@ finish: log_error("Failed to execute /bin/sh, giving up: %m"); } else log_warning("Failed to execute /sbin/init, giving up: %m"); + + sigprocmask(SIG_SETMASK, &o_ss, NULL); } if (arg_serialization) {