#include "kmod-setup.h"
#include "locale-setup.h"
#include "selinux-setup.h"
+#include "machine-id-setup.h"
#include "load-fragment.h"
#include "fdset.h"
#include "special.h"
#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;
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;
" 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;
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" },
- { "DefaultControllers", config_parse_strv, &arg_default_controllers, "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 }
};
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[] = {
#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 }
};
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) {
" --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;
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;
}
static void test_mtab(void) {
char *p;
+ /* Check that /etc/mtab is a symlink */
+
if (readlink_malloc("/etc/mtab", &p) >= 0) {
bool b;
return;
}
- log_error("/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.");
+ 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) {
+ 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.");
}
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;
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;
kmod_setup();
hostname_setup();
+ machine_id_setup();
loopback_setup();
mkdir_p("/dev/.systemd/ask-password/", 0755);
test_mtab();
+ test_usr();
}
if ((r = manager_new(arg_running_as, &m)) < 0) {
#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);
manager_free(m);
free(arg_default_unit);
- free(arg_console);
strv_free(arg_default_controllers);
dbus_shutdown();