[systemd-commits] 2 commits - Makefile.am man/journald.conf.xml man/kernel-command-line.xml man/systemd-journald.service.xml src/journal src/shared src/shutdownd src/systemctl src/tty-ask-password-agent

Lennart Poettering lennart at kemper.freedesktop.org
Fri Mar 14 14:05:42 PDT 2014


 Makefile.am                                         |    2 
 man/journald.conf.xml                               |   40 ++++++-----
 man/kernel-command-line.xml                         |    1 
 man/systemd-journald.service.xml                    |    5 -
 src/journal/journald-gperf.gperf                    |    2 
 src/journal/journald-native.c                       |    4 +
 src/journal/journald-server.c                       |    8 ++
 src/journal/journald-server.h                       |    2 
 src/journal/journald-stream.c                       |    4 +
 src/journal/journald-syslog.c                       |    4 +
 src/journal/journald-wall.c                         |   69 ++++++++++++++++++++
 src/journal/journald-wall.h                         |   26 +++++++
 src/journal/journald.conf                           |    2 
 src/shared/utmp-wtmp.c                              |   12 ++-
 src/shared/utmp-wtmp.h                              |    2 
 src/shutdownd/shutdownd.c                           |    2 
 src/systemctl/systemctl.c                           |    4 -
 src/tty-ask-password-agent/tty-ask-password-agent.c |    2 
 18 files changed, 164 insertions(+), 27 deletions(-)

New commits:
commit 40b71e89bae4e51768db4dc50ec64c1e9c96eec4
Author: Sebastian Thorarensen <sebth at naju.se>
Date:   Fri Mar 14 00:38:15 2014 +0100

    journald: add support for wall forwarding
    
    This will let journald forward logs as messages sent to all logged in
    users (like wall).
    
    Two options are added:
     * ForwardToWall (default yes)
     * MaxLevelWall (default emerg)
    'ForwardToWall' is overridable by kernel command line option
    'systemd.journald.forward_to_wall'.
    
    This is used to emulate the traditional syslogd behaviour of sending
    emergency messages to all logged in users.

diff --git a/Makefile.am b/Makefile.am
index 311ff09..60cb991 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3247,6 +3247,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..239a2ec 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 and
+                                wall 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/man/kernel-command-line.xml b/man/kernel-command-line.xml
index afcff7c..dbfec61 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -207,6 +207,7 @@
                                 <term><varname>systemd.journald.forward_to_syslog=</varname></term>
                                 <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
                                 <term><varname>systemd.journald.forward_to_console=</varname></term>
+                                <term><varname>systemd.journald.forward_to_wall=</varname></term>
 
                                 <listitem>
                                         <para>Parameters understood by
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index 4d2cb40..f0ce7aa 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -142,11 +142,12 @@
                                 <term><varname>systemd.journald.forward_to_syslog=</varname></term>
                                 <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
                                 <term><varname>systemd.journald.forward_to_console=</varname></term>
+                                <term><varname>systemd.journald.forward_to_wall=</varname></term>
 
                                 <listitem><para>Enables/disables
                                 forwarding of collected log messages
-                                to syslog, the kernel log buffer or
-                                the system console.
+                                to syslog, the kernel log buffer, the
+                                system console or wall.
                                 </para>
 
                                 <para>See
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 8680650..f0117e7 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.");
         }
@@ -1466,11 +1472,13 @@ int server_init(Server *s) {
         s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
 
         s->forward_to_syslog = true;
+        s->forward_to_wall = true;
 
         s->max_level_store = LOG_DEBUG;
         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..fcbd918
--- /dev/null
+++ b/src/journal/journald-wall.c
@@ -0,0 +1,69 @@
+/*-*- 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) {
+
+        _cleanup_free_ char *ident_buf = NULL, *l_buf = NULL;
+        const char *l;
+        int r;
+
+        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;
+                }
+
+                if (asprintf(&l_buf, "%s["PID_FMT"]: %s", strempty(identifier), ucred->pid, message) < 0) {
+                        log_oom();
+                        return;
+                }
+
+                l = l_buf;
+
+        } else if (identifier) {
+
+                l = l_buf = strjoin(identifier, ": ", message, NULL);
+                if (!l_buf) {
+                        log_oom();
+                        return;
+                }
+        } else
+                l = message;
+
+        r = utmp_wall(l, "systemd-journald", NULL);
+        if (r < 0)
+                log_debug("Failed to send wall message: %s", strerror(-r));
+}
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..d106d00 100644
--- a/src/journal/journald.conf
+++ b/src/journal/journald.conf
@@ -26,8 +26,10 @@
 #ForwardToSyslog=yes
 #ForwardToKMsg=no
 #ForwardToConsole=no
+#ForwardToWall=yes
 #TTYPath=/dev/console
 #MaxLevelStore=debug
 #MaxLevelSyslog=debug
 #MaxLevelKMsg=notice
 #MaxLevelConsole=info
+#MaxLevelWall=emerg

commit 9003d9b0d628be059922e522fd35f9c5b4d8b039
Author: Sebastian Thorarensen <sebth at naju.se>
Date:   Fri Mar 14 00:38:05 2014 +0100

    utmp-wtmp: allow overriding username on wall
    
    utmp_wall() now takes an optional argument 'username_override' which
    allows the caller to override the username shown on wall messages.
    journald will use this to inform users that its wall messages comes from
    'systemd-journald'.

diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index 32996fa..30a0c03 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -347,16 +347,20 @@ static int write_to_terminal(const char *tty, const char *message) {
         return 0;
 }
 
-int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) {
+int utmp_wall(const char *message, const char *username, bool (*match_tty)(const char *tty)) {
         _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL;
         char date[FORMAT_TIMESTAMP_MAX];
         struct utmpx *u;
         int r;
 
         hn = gethostname_malloc();
-        un = getlogname_malloc();
-        if (!hn || !un)
+        if (!hn)
                 return -ENOMEM;
+        if (!username) {
+                un = getlogname_malloc();
+                if (!un)
+                        return -ENOMEM;
+        }
 
         getttyname_harder(STDIN_FILENO, &tty);
 
@@ -364,7 +368,7 @@ int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) {
                      "\a\r\n"
                      "Broadcast message from %s@%s%s%s (%s):\r\n\r\n"
                      "%s\r\n\r\n",
-                     un, hn,
+                     un ?: username, hn,
                      tty ? " on " : "", strempty(tty),
                      format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
                      message) < 0)
diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h
index 5924023..040a16e 100644
--- a/src/shared/utmp-wtmp.h
+++ b/src/shared/utmp-wtmp.h
@@ -32,4 +32,4 @@ int utmp_put_runlevel(int runlevel, int previous);
 int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
 int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line);
 
-int utmp_wall(const char *message, bool (*match_tty)(const char *tty));
+int utmp_wall(const char *message, const char *username, bool (*match_tty)(const char *tty));
diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c
index 8d034e6..fafd9ce 100644
--- a/src/shutdownd/shutdownd.c
+++ b/src/shutdownd/shutdownd.c
@@ -143,7 +143,7 @@ static void warn_wall(usec_t n, struct sd_shutdown_command *c) {
 
         if (asprintf(&l, "%s%s%s%s!", c->wall_message, c->wall_message[0] ? "\n" : "",
                      prefix, format_timestamp(date, sizeof(date), c->usec)) >= 0)
-                utmp_wall(l, NULL);
+                utmp_wall(l, NULL, NULL);
         else
                 log_error("Failed to allocate wall message");
 }
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 254ca10..156605d 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -257,7 +257,7 @@ static void warn_wall(enum action a) {
                 }
 
                 if (*p) {
-                        utmp_wall(p, NULL);
+                        utmp_wall(p, NULL, NULL);
                         return;
                 }
         }
@@ -265,7 +265,7 @@ static void warn_wall(enum action a) {
         if (!table[a])
                 return;
 
-        utmp_wall(table[a], NULL);
+        utmp_wall(table[a], NULL, NULL);
 }
 
 static bool avoid_bus(void) {
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 7a90e65..fa4d660 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -538,7 +538,7 @@ static int show_passwords(void) {
                 free(p);
 
                 if (wall) {
-                        utmp_wall(wall, wall_tty_match);
+                        utmp_wall(wall, NULL, wall_tty_match);
                         free(wall);
                 }
         }



More information about the systemd-commits mailing list