Currently it is possible to either output legacy initscripts on console which often messes it up completely, or suppress output alltogether which makes it hard to debug boot issues.
While DefaultStandardOutput could be used to force syslog, it will affect *all* services, also those that set stdin to tty and rely on inheriting it. So make it possible for SysV to explicitly control output. Signed-off-by: Andrey Borzenkov <[email protected]> --- man/systemd.conf.xml | 2 + man/systemd.xml | 39 +++++++++++++++++++++++++++++++++++- src/dbus-manager.c | 4 +++ src/main.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++- src/manager.h | 1 + src/service.c | 5 +++- src/system.conf | 2 + 7 files changed, 101 insertions(+), 4 deletions(-) diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml index 8faedda..2d73d6e 100644 --- a/man/systemd.conf.xml +++ b/man/systemd.conf.xml @@ -80,6 +80,8 @@ <term><varname>CrashShell=no</varname></term> <term><varname>ShowStatus=yes</varname></term> <term><varname>SysVConsole=yes</varname></term> + <term><varname>SysVStandardOutput=inherit</varname></term> + <term><varname>SysVStandardError=inherit</varname></term> <term><varname>CrashChVT=1</varname></term> <term><varname>DefaultStandardOutput=null</varname></term> <term><varname>DefaultStandardError=inherit</varname></term> diff --git a/man/systemd.xml b/man/systemd.xml index 2c42a02..7f97d39 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -194,8 +194,8 @@ <varlistentry> <term><option>--sysv-console=</option></term> - <listitem><para>Controls whether - output of SysV init scripts will be + <listitem><para>Forces + output of SysV init scripts to be directed to the console. This switch has no effect when run as user instance. Takes a boolean argument @@ -204,6 +204,29 @@ <option>true</option>.</para></listitem> </varlistentry> <varlistentry> + <term><option>--sysv-standard-output=</option></term> + <term><option>--sysv-standard-error=</option></term> + + <listitem><para>Sets the default + output resp. error output for SysV + init scripts, i.e. controls + the default for + <option>StandardOutput=</option> + resp. <option>StandardExecute=</option> + (see + <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details). Takes one of + <option>inherit</option>, + <option>null</option>, + <option>tty</option>, + <option>syslog</option>, + <option>syslog+console</option>, + <option>kmsg</option>, + <option>kmsg-console</option>. If the + argument is omitted it defaults to + <option>inherit</option>.</para></listitem> + </varlistentry> + <varlistentry> <term><option>--log-target=</option></term> <listitem><para>Set log @@ -993,6 +1016,18 @@ </varlistentry> <varlistentry> + <term><varname>systemd.sysv_standard_output=</varname></term> + <term><varname>systemd.sysv_standard_error=</varname></term> + <listitem><para>Controls default + standard output/error output for + SysV init scripts, with the same effect as the + <option>--sysv-standard-output=</option> + resp. <option>--sysv-standard-error=</option> + command line arguments described + above.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>systemd.log_target=</varname></term> <term><varname>systemd.log_level=</varname></term> <term><varname>systemd.log_color=</varname></term> diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 6f98aa7..d1cdcb1 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -175,6 +175,8 @@ #ifdef HAVE_SYSV_COMPAT #define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \ " <property name=\"SysVConsole\" type=\"b\" access=\"read\"/>\n" \ + " <property name=\"SysVStandardOutput\" type=\"s\" access=\"read\"/>\n" \ + " <property name=\"SysVStandardError\" type=\"s\" access=\"read\"/>\n" \ " <property name=\"SysVInitPath\" type=\"as\" access=\"read\"/>\n" \ " <property name=\"SysVRcndPath\" type=\"as\" access=\"read\"/>\n" #else @@ -329,6 +331,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, { "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", "SysVStandardOutput", bus_manager_append_exec_output, "s", &m->sysv_std_output }, + { "org.freedesktop.systemd1.Manager", "SysVStandardError", bus_manager_append_exec_output, "s", &m->sysv_std_error }, { "org.freedesktop.systemd1.Manager", "SysVInitPath", bus_property_append_strv, "as", m->lookup_paths.sysvinit_path }, { "org.freedesktop.systemd1.Manager", "SysVRcndPath", bus_property_append_strv, "as", m->lookup_paths.sysvrcnd_path }, #endif diff --git a/src/main.c b/src/main.c index 96a282a..13fc069 100644 --- a/src/main.c +++ b/src/main.c @@ -69,6 +69,8 @@ static bool arg_confirm_spawn = false; static bool arg_show_status = true; #ifdef HAVE_SYSV_COMPAT static bool arg_sysv_console = true; +static ExecOutput arg_sysv_std_output = EXEC_OUTPUT_INHERIT; +static ExecOutput arg_sysv_std_error = EXEC_OUTPUT_INHERIT; #endif static bool arg_mount_auto = true; static bool arg_swap_auto = true; @@ -322,6 +324,20 @@ static int parse_proc_cmdline_word(const char *word) { log_warning("Failed to parse SysV console switch %s, Ignoring.", word + 20); else arg_sysv_console = r; + } else if (startswith(word, "systemd.sysv_std_output=")) { + int r; + + if ((r = exec_output_from_string(word + 24)) < 0) + log_warning("Failed to parse SysV standard output switch %s, Ignoring.", word + 24); + else + arg_sysv_std_output = r; + } else if (startswith(word, "systemd.sysv_std_error=")) { + int r; + + if ((r = exec_output_from_string(word + 23)) < 0) + log_warning("Failed to parse SysV standard error switch %s, Ignoring.", word + 23); + else + arg_sysv_std_error = r; #endif } else if (startswith(word, "systemd.")) { @@ -500,6 +516,8 @@ static int parse_config_file(void) { { "ShowStatus", config_parse_bool, &arg_show_status, "Manager" }, #ifdef HAVE_SYSV_COMPAT { "SysVConsole", config_parse_bool, &arg_sysv_console, "Manager" }, + { "SysVStandardOutput", config_parse_output, &arg_sysv_std_output, "Manager" }, + { "SysVStandardError", config_parse_output, &arg_sysv_std_error, "Manager" }, #endif { "CrashChVT", config_parse_int, &arg_crash_chvt, "Manager" }, { "CPUAffinity", config_parse_cpu_affinity, NULL, "Manager" }, @@ -586,7 +604,11 @@ static int parse_argv(int argc, char *argv[]) { ARG_CRASH_SHELL, ARG_CONFIRM_SPAWN, ARG_SHOW_STATUS, +#ifdef HAVE_SYSV_COMPAT ARG_SYSV_CONSOLE, + ARG_SYSV_STD_OUTPUT, + ARG_SYSV_STD_ERROR, +#endif ARG_DESERIALIZE, ARG_INTROSPECT, ARG_DEFAULT_STD_OUTPUT, @@ -610,6 +632,8 @@ static int parse_argv(int argc, char *argv[]) { { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, #ifdef HAVE_SYSV_COMPAT { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE }, + { "sysv-std-output", required_argument, NULL, ARG_SYSV_STD_OUTPUT }, + { "sysv-std-error", required_argument, NULL, ARG_SYSV_STD_ERROR }, #endif { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, { "introspect", optional_argument, NULL, ARG_INTROSPECT }, @@ -746,6 +770,22 @@ static int parse_argv(int argc, char *argv[]) { } else arg_sysv_console = true; break; + case ARG_SYSV_STD_OUTPUT: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse SysV standard output setting %s.", optarg); + return r; + } else + arg_sysv_std_output = r; + break; + case ARG_SYSV_STD_ERROR: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse SysV standard error setting %s.", optarg); + return r; + } else + arg_sysv_std_error = r; + break; #endif case ARG_DESERIALIZE: { @@ -836,6 +876,8 @@ static int help(void) { " --show-status[=0|1] Show status updates on the console during bootup\n" #ifdef HAVE_SYSV_COMPAT " --sysv-console[=0|1] Connect output of SysV scripts to console\n" + " --sysv-std-output= Set default standard output of SysV scripts\n" + " --sysv-std-error= Set default standard error of SysV scripts\n" #endif " --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" @@ -1114,6 +1156,8 @@ int main(int argc, char *argv[]) { m->show_status = arg_show_status; #ifdef HAVE_SYSV_COMPAT m->sysv_console = arg_sysv_console; + m->sysv_std_output = arg_sysv_std_output; + m->sysv_std_error = arg_sysv_std_error; #endif m->mount_auto = arg_mount_auto; m->swap_auto = arg_swap_auto; @@ -1254,7 +1298,7 @@ finish: label_finish(); if (reexecute) { - const char *args[15]; + const char *args[19]; unsigned i = 0; char sfd[16]; @@ -1293,6 +1337,12 @@ finish: args[i++] = "--sysv-console=1"; else args[i++] = "--sysv-console=0"; + + args[i++] = "--sysv-std-output"; + args[i++] = exec_output_to_string(arg_sysv_std_output); + + args[i++] = "--sysv-std-error"; + args[i++] = exec_output_to_string(arg_sysv_std_error); #endif snprintf(sfd, sizeof(sfd), "%i", fileno(serialization)); diff --git a/src/manager.h b/src/manager.h index 1967968..be9f3c9 100644 --- a/src/manager.h +++ b/src/manager.h @@ -215,6 +215,7 @@ struct Manager { bool confirm_spawn; #ifdef HAVE_SYSV_COMPAT bool sysv_console; + ExecOutput sysv_std_output, sysv_std_error; #endif bool mount_auto; bool swap_auto; diff --git a/src/service.c b/src/service.c index e928d1a..94603dc 100644 --- a/src/service.c +++ b/src/service.c @@ -819,7 +819,10 @@ 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 : s->meta.manager->default_std_output; + ? EXEC_OUTPUT_TTY : s->meta.manager->sysv_std_output; + s->exec_context.std_error = + (s->meta.manager->sysv_console || s->exec_context.std_input == EXEC_INPUT_TTY) + ? EXEC_OUTPUT_TTY : s->meta.manager->sysv_std_error; s->exec_context.kill_mode = KILL_PROCESS_GROUP; /* We use the long description only if diff --git a/src/system.conf b/src/system.conf index 4e06319..22195eb 100644 --- a/src/system.conf +++ b/src/system.conf @@ -16,6 +16,8 @@ #CrashShell=no #ShowStatus=yes #SysVConsole=yes +#SysVStandardOutput=inherit +#SysVStandardError=inherit #CrashChVT=1 #CPUAffinity=1 2 #MountAuto=yes -- tg: (2588ff0..) upstream/sysv-stdout (depends on: v18) _______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
