X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fmain.c;h=7edd6b5811b145d312ac0f0ced09945e6b72d7cb;hb=d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2b;hp=a041a22edaf819a44fa9186ab9ef38a35ab519d8;hpb=d7ccca2e3f86feb81a48e243d8bad78814659a74;p=elogind.git diff --git a/src/main.c b/src/main.c index a041a22ed..7edd6b581 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,7 @@ #include "label.h" #include "build.h" #include "strv.h" +#include "def.h" static enum { ACTION_RUN, @@ -226,6 +227,7 @@ static int parse_proc_cmdline_word(const char *word) { static const char * const rlmap[] = { "emergency", SPECIAL_EMERGENCY_TARGET, + "-b", SPECIAL_EMERGENCY_TARGET, "single", SPECIAL_RESCUE_TARGET, "-s", SPECIAL_RESCUE_TARGET, "s", SPECIAL_RESCUE_TARGET, @@ -544,6 +546,11 @@ static int parse_proc_cmdline(void) { int r; size_t l; + /* 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; + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return 0; @@ -624,7 +631,10 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 1); assert(argv); - while ((c = getopt_long(argc, argv, "hD", options, NULL)) >= 0) + if (getpid() == 1) + opterr = 0; + + while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0) switch (c) { @@ -800,23 +810,48 @@ static int parse_argv(int argc, char *argv[]) { log_set_max_level(LOG_DEBUG); break; - case '?': - return -EINVAL; + case 'b': + case 's': + case 'z': + /* Just to eat away the sysvinit kernel + * cmdline args without getopt() error + * messages that we'll parse in + * parse_proc_cmdline_word() or ignore. */ + case '?': default: - log_error("Unknown option code %c", c); - return -EINVAL; + if (getpid() != 1) { + log_error("Unknown option code %c", c); + return -EINVAL; + } + + break; } - /* PID 1 will get the kernel arguments as parameters, which we - * ignore and unconditionally read from - * /proc/cmdline. However, we need to ignore those arguments - * here. */ - if (arg_running_as != MANAGER_SYSTEM && optind < argc) { + if (optind < argc && getpid() != 1) { + /* Hmm, when we aren't run as init system + * let's complain about excess arguments */ + log_error("Excess arguments."); return -EINVAL; } + if (detect_container(NULL) > 0) { + char **a; + + /* All /proc/cmdline arguments the kernel didn't + * understand it passed to us. We're not really + * interested in that usually since /proc/cmdline is + * more interesting and complete. With one exception: + * if we are run in a container /proc/cmdline is not + * 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) + return r; + } + return 0; } @@ -942,25 +977,13 @@ static void test_mtab(void) { } static void test_usr(void) { - bool separate = false; /* Check that /usr is not a separate fs */ - if (path_is_mount_point("/usr") > 0) - separate = true; - /* This check won't work usually during boot, since /usr is - * probably not mounted yet, hence let's add a second - * check. We just check whether /usr is an empty directory. */ - if (dir_is_empty("/usr") > 0) - separate = true; - - if (!separate) - return; - - log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " - "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."); + log_warning("/usr appears to be on a different file system than /. This is not supported anymore. " + "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."); } int main(int argc, char *argv[]) { @@ -996,7 +1019,7 @@ int main(int argc, char *argv[]) { if (getpid() == 1) { arg_running_as = MANAGER_SYSTEM; - log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_SYSLOG_OR_KMSG); /* This might actually not return, but cause a * reexecution */ @@ -1042,9 +1065,16 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_running_as == MANAGER_SYSTEM && + arg_action == ACTION_RUN && + running_in_chroot() > 0) { + log_error("Cannot be run in a chroot() environment."); + goto finish; + } + /* If Plymouth is being run make sure we show the status, so * that there's something nice to see when people press Esc */ - if (access("/dev/.systemd/plymouth", F_OK) >= 0) + if (access("/dev/.run/initramfs/plymouth", F_OK) >= 0) arg_show_status = true; if (arg_action == ACTION_HELP) { @@ -1086,6 +1116,9 @@ int main(int argc, char *argv[]) { * kernel that don't really make sense for us. */ unsetenv("HOME"); unsetenv("TERM"); + + /* All other variables are left as is, so that clients + * can still read them via /proc/1/environ */ } /* Move out of the way, so that we won't block unmounts */ @@ -1131,8 +1164,6 @@ int main(int argc, char *argv[]) { machine_id_setup(); loopback_setup(); - mkdir_p("/dev/.systemd/ask-password/", 0755); - test_mtab(); test_usr(); }