diff --git a/TODO b/TODO index 5d60bdbbcc..572816b619 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,8 @@ Bugs: * systemctl default is started when we type "reboot" at rescue mode prompt +* mkswap/mke2fs aus cryptsetup unit muss vor dem mounten ausgeführt werden. + Features: * look up crypto partition mount points via fstab to show to the user when prompting for a password @@ -124,8 +126,6 @@ Features: * allow runtime changing of log level and target -* global defaults for StandardOuput=xxx - Fedora: * chkconfig → systemd enable/daemon-reload glue diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml index 54a8398d43..8faedda6c2 100644 --- a/man/systemd.conf.xml +++ b/man/systemd.conf.xml @@ -81,6 +81,8 @@ ShowStatus=yes SysVConsole=yes CrashChVT=1 + DefaultStandardOutput=null + DefaultStandardError=inherit Configures various parameters of basic manager diff --git a/man/systemd.xml b/man/systemd.xml index 88904b7a09..eff093a0f1 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -250,6 +250,30 @@ it defaults to . + + + + + Sets the default + output resp. error output for all + services and sockets, i.e. controls + the default for + + resp. + (see + systemd.exec5 + for details). Takes one of + , + , + , + , + , + , + . If the + argument is omitted it defaults to + + resp. . + @@ -981,6 +1005,18 @@ environment variables described above. + + systemd.default_standard_output= + systemd.default_standard_error= + Controls default + standard output/error output for + services, with the same effect as the + + resp. + command line arguments described + above. + + diff --git a/src/dbus-manager.c b/src/dbus-manager.c index d160e7bba3..6f98aa7308 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -168,8 +168,9 @@ " \n" \ " \n" \ " \n" \ - " \n" - \ + " \n" \ + " \n" \ + " \n" #ifdef HAVE_SYSV_COMPAT #define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \ @@ -205,6 +206,7 @@ const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_exec_output, exec_output, ExecOutput); static int bus_manager_append_log_target(Manager *m, DBusMessageIter *i, const char *property, void *data) { const char *t; @@ -323,6 +325,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, { "org.freedesktop.systemd1.Manager", "MountAuto", bus_property_append_bool, "b", &m->mount_auto }, { "org.freedesktop.systemd1.Manager", "SwapAuto", bus_property_append_bool, "b", &m->swap_auto }, { "org.freedesktop.systemd1.Manager", "DefaultControllers", bus_property_append_strv, "as", m->default_controllers }, + { "org.freedesktop.systemd1.Manager", "DefaultStandardOutput", bus_manager_append_exec_output, "s", &m->default_std_output }, + { "org.freedesktop.systemd1.Manager", "DefaultStandardError", bus_manager_append_exec_output, "s", &m->default_std_error }, #ifdef HAVE_SYSV_COMPAT { "org.freedesktop.systemd1.Manager", "SysVConsole", bus_property_append_bool, "b", &m->sysv_console }, { "org.freedesktop.systemd1.Manager", "SysVInitPath", bus_property_append_strv, "as", m->lookup_paths.sysvinit_path }, diff --git a/src/main.c b/src/main.c index d9dd0ac492..8512e0b1d4 100644 --- a/src/main.c +++ b/src/main.c @@ -73,6 +73,8 @@ static bool arg_sysv_console = true; static bool arg_mount_auto = true; static bool arg_swap_auto = true; static char **arg_default_controllers = NULL; +static ExecOutput arg_default_std_output = EXEC_OUTPUT_NULL; +static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; static FILE* serialization = NULL; @@ -298,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; @@ -326,7 +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"); + "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; @@ -466,24 +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" }, - { "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 } }; @@ -564,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[] = { @@ -587,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 } }; @@ -640,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) { @@ -794,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; @@ -1069,6 +1117,8 @@ 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; diff --git a/src/manager.c b/src/manager.c index 7d0b351c9d..a7c8885e80 100644 --- a/src/manager.c +++ b/src/manager.c @@ -214,6 +214,8 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->pin_cgroupfs_fd = -1; + m->default_std_output = EXEC_OUTPUT_NULL; + #ifdef HAVE_AUDIT m->audit_fd = -1; #endif diff --git a/src/manager.h b/src/manager.h index a329ee925f..19679686b1 100644 --- a/src/manager.h +++ b/src/manager.h @@ -219,6 +219,8 @@ struct Manager { bool mount_auto; bool swap_auto; + ExecOutput default_std_output, default_std_error; + int n_deserializing; unsigned n_installed_jobs; diff --git a/src/mount.c b/src/mount.c index d9f3da6c48..1f311cee41 100644 --- a/src/mount.c +++ b/src/mount.c @@ -64,6 +64,7 @@ static void mount_init(Unit *u) { m->directory_mode = 0755; exec_context_init(&m->exec_context); + m->exec_context.std_output = EXEC_OUTPUT_KMSG; /* We need to make sure that /bin/mount is always called in * the same process group as us, so that the autofs kernel diff --git a/src/service.c b/src/service.c index 243e5536a7..e928d1a5e0 100644 --- a/src/service.c +++ b/src/service.c @@ -121,6 +121,8 @@ static void service_init(Unit *u) { s->guess_main_pid = true; exec_context_init(&s->exec_context); + s->exec_context.std_output = u->meta.manager->default_std_output; + s->exec_context.std_error = u->meta.manager->default_std_error; RATELIMIT_INIT(s->ratelimit, 10*USEC_PER_SEC, 5); @@ -817,7 +819,7 @@ static int service_load_sysv_path(Service *s, const char *path) { s->restart = SERVICE_RESTART_NO; s->exec_context.std_output = (s->meta.manager->sysv_console || s->exec_context.std_input == EXEC_INPUT_TTY) - ? EXEC_OUTPUT_TTY : EXEC_OUTPUT_NULL; + ? EXEC_OUTPUT_TTY : s->meta.manager->default_std_output; s->exec_context.kill_mode = KILL_PROCESS_GROUP; /* We use the long description only if diff --git a/src/socket.c b/src/socket.c index 3f57e35350..c41130ce72 100644 --- a/src/socket.c +++ b/src/socket.c @@ -77,6 +77,8 @@ static void socket_init(Unit *u) { s->mark = -1; exec_context_init(&s->exec_context); + s->exec_context.std_output = u->meta.manager->default_std_output; + s->exec_context.std_error = u->meta.manager->default_std_error; s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; } diff --git a/src/swap.c b/src/swap.c index 9a253beea2..4124f75852 100644 --- a/src/swap.c +++ b/src/swap.c @@ -82,6 +82,7 @@ static void swap_unset_proc_swaps(Swap *s) { s->timeout_usec = DEFAULT_TIMEOUT_USEC; exec_context_init(&s->exec_context); + s->exec_context.std_output = EXEC_OUTPUT_KMSG; s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; diff --git a/src/system.conf b/src/system.conf index c94cf3601f..bd5a1a7894 100644 --- a/src/system.conf +++ b/src/system.conf @@ -5,7 +5,7 @@ # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # -# See systemd(1) for details +# See systemd.conf(5) for details [Manager] #LogLevel=info @@ -21,3 +21,5 @@ #MountAuto=yes #SwapAuto=yes #DefaultControllers=cpu +#DefaultStandardOutput=null +#DefaultStandardError=inherit diff --git a/units/systemd-logger.service.in b/units/systemd-logger.service.in index d9708724e1..ff7a1316c2 100644 --- a/units/systemd-logger.service.in +++ b/units/systemd-logger.service.in @@ -15,3 +15,4 @@ After=syslog.socket [Service] ExecStart=@rootlibexecdir@/systemd-logger NotifyAccess=all +StandardOutput=null