On Wed, Mar 05, 2014 at 01:45:51PM +0100, Sebastian Thorarensen wrote: > This will let journald forward logs as messages sent to all logged in > users (like wall). > > Two options are added: > * ForwardToWall (default no) Is there a good reason not to set it to yes by default?
> * MaxLevelWall (default emerg) > 'ForwardToWall' is overridable by kernel command line option > 'systemd.journald.forward_to_wall'. > > This can be used to emulate the traditional syslogd behaviour of sending > emergency messages to all logged in users. > --- > Makefile.am | 2 ++ > man/journald.conf.xml | 40 +++++++++++++++----------- > src/journal/journald-gperf.gperf | 2 ++ > src/journal/journald-native.c | 4 +++ > src/journal/journald-server.c | 7 +++++ > src/journal/journald-server.h | 2 ++ > src/journal/journald-stream.c | 4 +++ > src/journal/journald-syslog.c | 4 +++ > src/journal/journald-wall.c | 59 > ++++++++++++++++++++++++++++++++++++++ > src/journal/journald-wall.h | 26 +++++++++++++++++ > src/journal/journald.conf | 2 ++ > 11 files changed, 136 insertions(+), 16 deletions(-) > create mode 100644 src/journal/journald-wall.c > create mode 100644 src/journal/journald-wall.h > > diff --git a/Makefile.am b/Makefile.am > index f99cef7..02a2fbf 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -3227,6 +3227,8 @@ libsystemd_journal_core_la_SOURCES = \ > src/journal/journald-server.h \ > src/journal/journald-console.c \ > src/journal/journald-console.h \ > + src/journal/journald-wall.c \ > + src/journal/journald-wall.h \ > src/journal/journald-native.c \ > src/journal/journald-native.h \ > src/journal/journald-rate-limit.c \ > diff --git a/man/journald.conf.xml b/man/journald.conf.xml > index a814ec1..723d445 100644 > --- a/man/journald.conf.xml > +++ b/man/journald.conf.xml > @@ -381,24 +381,28 @@ > > <term><varname>ForwardToSyslog=</varname></term> > > <term><varname>ForwardToKMsg=</varname></term> > > <term><varname>ForwardToConsole=</varname></term> > + > <term><varname>ForwardToWall=</varname></term> > > <listitem><para>Control whether log > messages received by the journal > daemon shall be forwarded to a > traditional syslog daemon, to the > - kernel log buffer (kmsg), or to the > - system console. These options take > - boolean arguments. If forwarding to > - syslog is enabled but no syslog daemon > - is running, the respective option has > - no effect. By default, only forwarding > - to syslog is enabled. These settings > - may be overridden at boot time with > - the kernel command line options > + kernel log buffer (kmsg), to the > + system console, or sent as wall > + messages to all logged-in users. These > + options take boolean arguments. If > + forwarding to syslog is enabled but no > + syslog daemon is running, the > + respective option has no effect. By > + default, only forwarding to syslog is > + enabled. These settings may be > + overridden at boot time with the > + kernel command line options > > <literal>systemd.journald.forward_to_syslog=</literal>, > - > <literal>systemd.journald.forward_to_kmsg=</literal> > + > <literal>systemd.journald.forward_to_kmsg=</literal>, > + > <literal>systemd.journald.forward_to_console=</literal> > and > - > <literal>systemd.journald.forward_to_console=</literal>. > + > <literal>systemd.journald.forward_to_wall=</literal>. > When forwarding to the console, the > TTY to log to can be changed > with <varname>TTYPath=</varname>, > @@ -410,12 +414,14 @@ > > <term><varname>MaxLevelSyslog=</varname></term> > <term><varname>MaxLevelKMsg=</varname></term> > > <term><varname>MaxLevelConsole=</varname></term> > + <term><varname>MaxLevelWall=</varname></term> > > <listitem><para>Controls the maximum > log level of messages that are stored > - on disk, forwarded to syslog, kmsg or > - the console (if that is enabled, see > - above). As argument, takes one of > + on disk, forwarded to syslog, kmsg, > + the console or wall (if that is > + enabled, see above). As argument, > + takes one of > <literal>emerg</literal>, > <literal>alert</literal>, > <literal>crit</literal>, > @@ -436,9 +442,11 @@ > written to disk and forwarded to > syslog. Defaults to > <literal>notice</literal> for > - <varname>MaxLevelKMsg=</varname> and > + <varname>MaxLevelKMsg=</varname>, > <literal>info</literal> for > - > <varname>MaxLevelConsole=</varname>.</para></listitem> > + <varname>MaxLevelConsole=</varname> and > + <literal>emerg</literal> for > + > <varname>MaxLevelWall=</varname>.</para></listitem> > </varlistentry> > > <varlistentry> > diff --git a/src/journal/journald-gperf.gperf > b/src/journal/journald-gperf.gperf > index 83bbbc8..74554c1 100644 > --- a/src/journal/journald-gperf.gperf > +++ b/src/journal/journald-gperf.gperf > @@ -32,9 +32,11 @@ Journal.MaxFileSec, config_parse_sec, 0, > offsetof(Server, max_fil > Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, > forward_to_syslog) > Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, > forward_to_kmsg) > Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, > forward_to_console) > +Journal.ForwardToWall, config_parse_bool, 0, offsetof(Server, > forward_to_wall) > Journal.TTYPath, config_parse_path, 0, offsetof(Server, > tty_path) > Journal.MaxLevelStore, config_parse_log_level, 0, offsetof(Server, > max_level_store) > Journal.MaxLevelSyslog, config_parse_log_level, 0, offsetof(Server, > max_level_syslog) > Journal.MaxLevelKMsg, config_parse_log_level, 0, offsetof(Server, > max_level_kmsg) > Journal.MaxLevelConsole, config_parse_log_level, 0, offsetof(Server, > max_level_console) > +Journal.MaxLevelWall, config_parse_log_level, 0, offsetof(Server, > max_level_wall) > Journal.SplitMode, config_parse_split_mode, 0, offsetof(Server, > split_mode) > diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c > index 359d962..0509c1e 100644 > --- a/src/journal/journald-native.c > +++ b/src/journal/journald-native.c > @@ -31,6 +31,7 @@ > #include "journald-kmsg.h" > #include "journald-console.h" > #include "journald-syslog.h" > +#include "journald-wall.h" > > /* Make sure not to make this smaller than the maximum coredump > * size. See COREDUMP_MAX in coredump.c */ > @@ -265,6 +266,9 @@ void server_process_native_message( > > if (s->forward_to_console) > server_forward_console(s, priority, identifier, > message, ucred); > + > + if (s->forward_to_wall) > + server_forward_wall(s, priority, identifier, > message, ucred); > } > > server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, > NULL, priority, object_pid); > diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c > index 2a90b44..2fcb4d7 100644 > --- a/src/journal/journald-server.c > +++ b/src/journal/journald-server.c > @@ -1319,6 +1319,12 @@ static int server_parse_proc_cmdline(Server *s) { > log_warning("Failed to parse forward to > console switch %s. Ignoring.", word + 36); > else > s->forward_to_console = r; > + } else if (startswith(word, > "systemd.journald.forward_to_wall=")) { > + r = parse_boolean(word + 33); > + if (r < 0) > + log_warning("Failed to parse forward to wall > switch %s. Ignoring.", word + 33); > + else > + s->forward_to_wall = r; > } else if (startswith(word, "systemd.journald")) > log_warning("Invalid systemd.journald parameter. > Ignoring."); > } > @@ -1471,6 +1477,7 @@ int server_init(Server *s) { > s->max_level_syslog = LOG_DEBUG; > s->max_level_kmsg = LOG_NOTICE; > s->max_level_console = LOG_INFO; > + s->max_level_wall = LOG_EMERG; > > memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics)); > memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics)); > diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h > index 2a81061..e468b82 100644 > --- a/src/journal/journald-server.h > +++ b/src/journal/journald-server.h > @@ -97,6 +97,7 @@ typedef struct Server { > bool forward_to_kmsg; > bool forward_to_syslog; > bool forward_to_console; > + bool forward_to_wall; > > unsigned n_forward_syslog_missed; > usec_t last_warn_forward_syslog_missed; > @@ -119,6 +120,7 @@ typedef struct Server { > int max_level_syslog; > int max_level_kmsg; > int max_level_console; > + int max_level_wall; > > Storage storage; > SplitMode split_mode; > diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c > index 36fc755..c46ffe5 100644 > --- a/src/journal/journald-stream.c > +++ b/src/journal/journald-stream.c > @@ -35,6 +35,7 @@ > #include "journald-syslog.h" > #include "journald-kmsg.h" > #include "journald-console.h" > +#include "journald-wall.h" > > #define STDOUT_STREAMS_MAX 4096 > > @@ -106,6 +107,9 @@ static int stdout_stream_log(StdoutStream *s, const char > *p) { > if (s->forward_to_console || s->server->forward_to_console) > server_forward_console(s->server, priority, s->identifier, > p, &s->ucred); > > + if (s->server->forward_to_wall) > + server_forward_wall(s->server, priority, s->identifier, p, > &s->ucred); > + > IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout"); > > syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority); > diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c > index 241f7ed..cbb944f 100644 > --- a/src/journal/journald-syslog.c > +++ b/src/journal/journald-syslog.c > @@ -30,6 +30,7 @@ > #include "journald-syslog.h" > #include "journald-kmsg.h" > #include "journald-console.h" > +#include "journald-wall.h" > > /* Warn once every 30s if we missed syslog message */ > #define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC) > @@ -380,6 +381,9 @@ void server_process_syslog_message( > if (s->forward_to_console) > server_forward_console(s, priority, identifier, buf, ucred); > > + if (s->forward_to_wall) > + server_forward_wall(s, priority, identifier, buf, ucred); > + > IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog"); > > if (asprintf(&syslog_priority, "PRIORITY=%i", priority & > LOG_PRIMASK) >= 0) > diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c > new file mode 100644 > index 0000000..55a44bd > --- /dev/null > +++ b/src/journal/journald-wall.c > @@ -0,0 +1,59 @@ > +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ > + > +/*** > + This file is part of systemd. > + > + Copyright 2014 Sebastian Thorarensen > + > + systemd is free software; you can redistribute it and/or modify it > + under the terms of the GNU Lesser General Public License as published by > + the Free Software Foundation; either version 2.1 of the License, or > + (at your option) any later version. > + > + systemd is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public License > + along with systemd; If not, see <http://www.gnu.org/licenses/>. > +***/ > + > +#include "utmp-wtmp.h" > +#include "journald-server.h" > +#include "journald-wall.h" > + > +void server_forward_wall( > + Server *s, > + int priority, > + const char *identifier, > + const char *message, > + struct ucred *ucred) { > + > + char header_pid[16]; header_pid[DECIMAL_STR_MAX(pid_t) + sizeof("[]"]; > + _cleanup_free_ char *ident_buf = NULL, *l = NULL; > + > + assert(s); > + assert(message); > + > + if (LOG_PRI(priority) > s->max_level_wall) > + return; > + > + if (ucred) { > + if (!identifier) { > + get_process_comm(ucred->pid, &ident_buf); > + identifier = ident_buf; > + } > + > + snprintf(header_pid, sizeof(header_pid), "[%lu]", (unsigned > long) ucred->pid); Use "["PID_FMT"]" for the format. > + char_array_0(header_pid); Remove this. > + } > + > + if (asprintf(&l, "%s%s: %s", strempty(identifier), > strempty(header_pid), message) < 0) { > + log_debug("Failed to allocate wall message: %m"); > + return; > + } > + > + if (utmp_wall(l, "systemd-journald", NULL) < 0) > + log_debug("Failed to send wall message: %m"); > +} > diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h > new file mode 100644 > index 0000000..93c3cec > --- /dev/null > +++ b/src/journal/journald-wall.h > @@ -0,0 +1,26 @@ > +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ > + > +#pragma once > + > +/*** > + This file is part of systemd. > + > + Copyright 2014 Sebastian Thorarensen > + > + systemd is free software; you can redistribute it and/or modify it > + under the terms of the GNU Lesser General Public License as published by > + the Free Software Foundation; either version 2.1 of the License, or > + (at your option) any later version. > + > + systemd is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public License > + along with systemd; If not, see <http://www.gnu.org/licenses/>. > +***/ > + > +#include "journald-server.h" > + > +void server_forward_wall(Server *s, int priority, const char *identifier, > const char *message, struct ucred *ucred); > diff --git a/src/journal/journald.conf b/src/journal/journald.conf > index 54f6833..16ea1f1 100644 > --- a/src/journal/journald.conf > +++ b/src/journal/journald.conf > @@ -26,8 +26,10 @@ > #ForwardToSyslog=yes > #ForwardToKMsg=no > #ForwardToConsole=no > +#ForwardToWall=no > #TTYPath=/dev/console > #MaxLevelStore=debug > #MaxLevelSyslog=debug > #MaxLevelKMsg=notice > #MaxLevelConsole=info > +#MaxLevelWall=emerg Zbyszek _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel