X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=a732c6945afc5a671d134e235cafd31e03241771;hp=29f2d5a2a55f7ca37fabea8eb60b3ba6a69048b9;hb=3408ba015aee3a88c91962c028738be757779519;hpb=5ae4d543cb9b45ad6c6b82b78da1d6abc2291cdb diff --git a/src/core/main.c b/src/core/main.c index 29f2d5a2a..a732c6945 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -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) { @@ -374,49 +375,17 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { } else log_warning("Environment variable name '%s' is not valid. Ignoring.", value); - } else if (!streq(key, "systemd.restore_state") && - !streq(key, "systemd.gpt_auto") && - (startswith(key, "systemd.") || startswith(key, "rd.systemd."))) { - - const char *c; - - /* Ignore systemd.journald.xyz and friends */ - c = key; - if (startswith(c, "rd.")) - c += 3; - if (startswith(c, "systemd.")) - c += 8; - if (c[strcspn(c, ".=")] != '.') { - - log_warning("Unknown kernel switch %s. Ignoring.", key); - - log_info("Supported kernel switches:\n" - "systemd.unit=UNIT Default unit to start\n" - "rd.systemd.unit=UNIT Default unit to start when run in initrd\n" - "systemd.dump_core=0|1 Dump core on crash\n" - "systemd.crash_shell=0|1 Run shell on crash\n" - "systemd.crash_chvt=N Change to VT #N on crash\n" - "systemd.confirm_spawn=0|1 Confirm every process spawn\n" - "systemd.show_status=0|1|auto Show status updates on the console during bootup\n" - "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n" - " Log target\n" - "systemd.log_level=LEVEL Log level\n" - "systemd.log_color=0|1 Highlight important log messages\n" - "systemd.log_location=0|1 Include code location in log messages\n" - "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" - " Set default log output for services\n" - "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" - " Set default log error output for services\n" - "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n" - "systemd.restore_state=0|1 Restore backlight/rfkill state at boot\n"); - } - } 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 +1120,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. " @@ -1296,6 +1271,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 }; @@ -1567,10 +1543,22 @@ int main(int argc, char *argv[]) { if (in_initrd()) log_info("Running in initial RAM disk."); + /* Let's check whether /etc is already populated. We + * don't actually really check for that, but use + * /etc/machine-id as flag file. 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.*/ + + empty_etc = access("/etc/machine-id", F_OK) < 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 ")", - getuid(), t); + _cleanup_free_ char *t; + + t = uid_to_name(getuid()); + log_debug(PACKAGE_STRING " running in user mode for user "UID_FMT"/%s. (" SYSTEMD_FEATURES ")", getuid(), strna(t)); } if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { @@ -1578,11 +1566,10 @@ 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(); @@ -1624,9 +1611,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)); @@ -1837,6 +1833,7 @@ finish: if (reexecute) { const char **args; unsigned i, args_size; + sigset_t ss; /* Close and disarm the watchdog, so that the new * instance can reinitialize it, but doesn't get @@ -1920,6 +1917,13 @@ finish: args[i++] = NULL; assert(i <= args_size); + /* reenable any blocked signals, especially important + * if we switch from initial ramdisk to init=... */ + reset_all_signal_handlers(); + + assert_se(sigemptyset(&ss) == 0); + assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0); + if (switch_root_init) { args[0] = switch_root_init; execv(args[0], (char* const*) args);