X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fmain.c;h=3291561e099bbacc0d45bec83013ae47d523b7e4;hp=ea2f0c1a9ecf3dc378257885ef96a86a34c7d86e;hb=aa1671320df5bd8aa4108c0efb34a49fdedd0e5f;hpb=f3b6a3edbce43df47374761529dd663c9a39c612 diff --git a/src/main.c b/src/main.c index ea2f0c1a9..3291561e0 100644 --- a/src/main.c +++ b/src/main.c @@ -49,6 +49,7 @@ #include "missing.h" #include "label.h" #include "build.h" +#include "strv.h" static enum { ACTION_RUN, @@ -71,7 +72,9 @@ static bool arg_sysv_console = true; #endif static bool arg_mount_auto = true; static bool arg_swap_auto = true; -static char *arg_console = NULL; +static char **arg_default_controllers = NULL; +static ExecOutput arg_default_std_output = EXEC_OUTPUT_INHERIT; +static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; static FILE* serialization = NULL; @@ -297,6 +300,20 @@ static int parse_proc_cmdline_word(const char *word) { log_warning("Failed to parse show status switch %s, Ignoring.", word + 20); else arg_show_status = r; + } else if (startswith(word, "systemd.default_standard_output=")) { + int r; + + if ((r = exec_output_from_string(word + 32)) < 0) + log_warning("Failed to parse default standard output switch %s, Ignoring.", word + 32); + else + arg_default_std_output = r; + } else if (startswith(word, "systemd.default_standard_error=")) { + int r; + + if ((r = exec_output_from_string(word + 31)) < 0) + log_warning("Failed to parse default standard error switch %s, Ignoring.", word + 31); + else + arg_default_std_error = r; #ifdef HAVE_SYSV_COMPAT } else if (startswith(word, "systemd.sysv_console=")) { int r; @@ -325,27 +342,11 @@ static int parse_proc_cmdline_word(const char *word) { " 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"); - - } else if (startswith(word, "console=")) { - const char *k; - size_t l; - char *w = NULL; - - k = word + 8; - l = strcspn(k, ","); - - /* Ignore the console setting if set to a VT */ - if (l < 4 || - !startswith(k, "tty") || - k[3+strspn(k+3, "0123456789")] != 0) { - - if (!(w = strndup(k, l))) - return -ENOMEM; - } - - free(arg_console); - arg_console = w; + "systemd.log_location=0|1 Include code location in log messages\n" + "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console\n" + " Set default log output for services\n" + "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console\n" + " Set default log error output for services\n"); } else if (streq(word, "quiet")) { arg_show_status = false; @@ -485,23 +486,28 @@ static int config_parse_cpu_affinity( return 0; } +static DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier"); + static int parse_config_file(void) { const ConfigItem items[] = { - { "LogLevel", config_parse_level, NULL, "Manager" }, - { "LogTarget", config_parse_target, NULL, "Manager" }, - { "LogColor", config_parse_color, NULL, "Manager" }, - { "LogLocation", config_parse_location, NULL, "Manager" }, - { "DumpCore", config_parse_bool, &arg_dump_core, "Manager" }, - { "CrashShell", config_parse_bool, &arg_crash_shell, "Manager" }, - { "ShowStatus", config_parse_bool, &arg_show_status, "Manager" }, + { "LogLevel", config_parse_level, NULL, "Manager" }, + { "LogTarget", config_parse_target, NULL, "Manager" }, + { "LogColor", config_parse_color, NULL, "Manager" }, + { "LogLocation", config_parse_location, NULL, "Manager" }, + { "DumpCore", config_parse_bool, &arg_dump_core, "Manager" }, + { "CrashShell", config_parse_bool, &arg_crash_shell, "Manager" }, + { "ShowStatus", config_parse_bool, &arg_show_status, "Manager" }, #ifdef HAVE_SYSV_COMPAT - { "SysVConsole", config_parse_bool, &arg_sysv_console, "Manager" }, + { "SysVConsole", config_parse_bool, &arg_sysv_console, "Manager" }, #endif - { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" }, - { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" }, - { "MountAuto", config_parse_bool, &arg_mount_auto, "Manager" }, - { "SwapAuto", config_parse_bool, &arg_swap_auto, "Manager" }, + { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" }, + { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" }, + { "MountAuto", config_parse_bool, &arg_mount_auto, "Manager" }, + { "SwapAuto", config_parse_bool, &arg_swap_auto, "Manager" }, + { "DefaultControllers", config_parse_strv, &arg_default_controllers, "Manager" }, + { "DefaultStandardOutput", config_parse_output, &arg_default_std_output, "Manager" }, + { "DefaultStandardError", config_parse_output, &arg_default_std_error, "Manager" }, { NULL, NULL, NULL, NULL } }; @@ -514,7 +520,7 @@ static int parse_config_file(void) { const char *fn; int r; - fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : SESSION_CONFIG_FILE; + fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE; if (!(f = fopen(fn, "re"))) { if (errno == ENOENT) @@ -573,7 +579,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_LOG_LOCATION, ARG_UNIT, ARG_SYSTEM, - ARG_SESSION, + ARG_USER, ARG_TEST, ARG_DUMP_CONFIGURATION_ITEMS, ARG_DUMP_CORE, @@ -582,7 +588,9 @@ static int parse_argv(int argc, char *argv[]) { ARG_SHOW_STATUS, ARG_SYSV_CONSOLE, ARG_DESERIALIZE, - ARG_INTROSPECT + ARG_INTROSPECT, + ARG_DEFAULT_STD_OUTPUT, + ARG_DEFAULT_STD_ERROR }; static const struct option options[] = { @@ -592,7 +600,7 @@ static int parse_argv(int argc, char *argv[]) { { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, { "unit", required_argument, NULL, ARG_UNIT }, { "system", no_argument, NULL, ARG_SYSTEM }, - { "session", no_argument, NULL, ARG_SESSION }, + { "user", no_argument, NULL, ARG_USER }, { "test", no_argument, NULL, ARG_TEST }, { "help", no_argument, NULL, 'h' }, { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS }, @@ -605,6 +613,8 @@ static int parse_argv(int argc, char *argv[]) { #endif { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, { "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 } }; @@ -658,6 +668,24 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_DEFAULT_STD_OUTPUT: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard output setting %s.", optarg); + return r; + } else + arg_default_std_output = r; + break; + + case ARG_DEFAULT_STD_ERROR: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard error output setting %s.", optarg); + return r; + } else + arg_default_std_error = r; + break; + case ARG_UNIT: if ((r = set_default_unit(optarg)) < 0) { @@ -671,8 +699,8 @@ static int parse_argv(int argc, char *argv[]) { arg_running_as = MANAGER_SYSTEM; break; - case ARG_SESSION: - arg_running_as = MANAGER_SESSION; + case ARG_USER: + arg_running_as = MANAGER_USER; break; case ARG_TEST: @@ -794,14 +822,14 @@ static int parse_argv(int argc, char *argv[]) { static int help(void) { printf("%s [OPTIONS...]\n\n" - "Starts up and maintains the system or a session.\n\n" + "Starts up and maintains the system or user services.\n\n" " -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" - " --session Run a session instance\n" + " --user Run a user instance\n" " --dump-core Dump core on crash\n" " --crash-shell Run shell on crash\n" " --confirm-spawn Ask for confirmation when spawning processes\n" @@ -812,7 +840,9 @@ static int help(void) { " --log-target=TARGET Set log target (console, syslog, kmsg, syslog-or-kmsg, null)\n" " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n" " --log-color[=0|1] Highlight important log messages\n" - " --log-location[=0|1] Include code location in log messages\n", + " --log-location[=0|1] Include code location in log messages\n" + " --default-standard-output= Set default standard output for services\n" + " --default-standard-error= Set default standard error output for services\n", program_invocation_short_name); return 0; @@ -828,7 +858,7 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds) { assert(_fds); if ((r = manager_open_serialization(m, &f)) < 0) { - log_error("Failed to create serialization faile: %s", strerror(-r)); + log_error("Failed to create serialization file: %s", strerror(-r)); goto fail; } @@ -890,6 +920,51 @@ static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) { return t; } +static void test_mtab(void) { + char *p; + + /* Check that /etc/mtab is a symlink */ + + if (readlink_malloc("/etc/mtab", &p) >= 0) { + bool b; + + b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts"); + free(p); + + if (b) + return; + } + + log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. " + "This is not supported anymore. " + "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output."); +} + +static void test_usr(void) { + struct stat a, b; + bool separate = false; + + /* Check that /usr is not a separate fs */ + + if (lstat("/", &a) >= 0 && lstat("/usr", &b) >= 0) + if (a.st_dev != b.st_dev) + 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."); +} + int main(int argc, char *argv[]) { Manager *m = NULL; int r, retval = EXIT_FAILURE; @@ -900,7 +975,7 @@ int main(int argc, char *argv[]) { char systemd[] = "systemd"; if (getpid() != 1 && strstr(program_invocation_short_name, "init")) { - /* This is compatbility support for SysV, where + /* This is compatibility support for SysV, where * calling init as a user is identical to telinit. */ errno = -ENOENT; @@ -933,7 +1008,7 @@ int main(int argc, char *argv[]) { if (label_init() < 0) goto finish; } else { - arg_running_as = MANAGER_SESSION; + arg_running_as = MANAGER_USER; log_set_target(LOG_TARGET_CONSOLE); } @@ -964,6 +1039,16 @@ int main(int argc, char *argv[]) { if (parse_argv(argc, argv) < 0) goto finish; + if (arg_action == ACTION_TEST && geteuid() == 0) { + log_error("Don't run test mode as root."); + 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) + arg_show_status = true; + if (arg_action == ACTION_HELP) { retval = help(); goto finish; @@ -1048,6 +1133,9 @@ int main(int argc, char *argv[]) { loopback_setup(); mkdir_p("/dev/.systemd/ask-password/", 0755); + + test_mtab(); + test_usr(); } if ((r = manager_new(arg_running_as, &m)) < 0) { @@ -1062,12 +1150,14 @@ int main(int argc, char *argv[]) { #endif m->mount_auto = arg_mount_auto; m->swap_auto = arg_swap_auto; + m->default_std_output = arg_default_std_output; + m->default_std_error = arg_default_std_error; if (dual_timestamp_is_set(&initrd_timestamp)) m->initrd_timestamp = initrd_timestamp; - if (arg_console) - manager_set_console(m, arg_console); + if (arg_default_controllers) + manager_set_default_controllers(m, arg_default_controllers); if ((r = manager_startup(m, serialization, fds)) < 0) log_error("Failed to fully start up daemon: %s", strerror(-r)); @@ -1190,7 +1280,7 @@ finish: manager_free(m); free(arg_default_unit); - free(arg_console); + strv_free(arg_default_controllers); dbus_shutdown(); @@ -1215,7 +1305,7 @@ finish: if (arg_running_as == MANAGER_SYSTEM) args[i++] = "--system"; else - args[i++] = "--session"; + args[i++] = "--user"; if (arg_dump_core) args[i++] = "--dump-core";