]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/journal/journald-kmsg.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / journal / journald-kmsg.c
index c96b84e61f841c8d7314d1a61b41a7d70e9a3692..8ae7a23d5662dad05cdc262b0b7545a18502beea 100644 (file)
@@ -19,6 +19,7 @@
 #include "journald-kmsg.h"
 #include "journald-server.h"
 #include "journald-syslog.h"
+#include "log.h"
 #include "parse-util.h"
 #include "process-util.h"
 #include "stdio-util.h"
@@ -106,6 +107,8 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
         char *e, *f, *k;
         uint64_t serial;
         size_t pl;
+        int saved_log_max_level = INT_MAX;
+        ClientContext *c = NULL;
 
         assert(s);
         assert(p);
@@ -266,10 +269,16 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
         else {
                 pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);
 
-                /* Avoid any messages we generated ourselves via
-                 * log_info() and friends. */
-                if (is_us(identifier, pid))
-                        goto finish;
+                /* Avoid logging any new messages when we're processing messages generated by ourselves via
+                 * log_info() and friends to avoid infinite loops. */
+                if (is_us(identifier, pid)) {
+                        if (!ratelimit_below(&s->kmsg_own_ratelimit))
+                                return;
+
+                        saved_log_max_level = log_get_max_level();
+                        c = s->my_context;
+                        log_set_max_level(LOG_NULL);
+                }
 
                 if (identifier) {
                         syslog_identifier = strjoin("SYSLOG_IDENTIFIER=", identifier);
@@ -287,7 +296,11 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
         if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0)
                 iovec[n++] = IOVEC_MAKE_STRING(message);
 
-        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority, 0);
+
+        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), c, NULL, priority, 0);
+
+        if (saved_log_max_level != INT_MAX)
+                log_set_max_level(saved_log_max_level);
 
 finish:
         for (j = 0; j < z; j++)
@@ -313,7 +326,7 @@ static int server_read_dev_kmsg(Server *s) {
                         return 0;
                 }
 
-                if (IN_SET(errno, EAGAIN, EINTR, EPIPE))
+                if (ERRNO_IS_TRANSIENT(errno) || errno == EPIPE)
                         return 0;
 
                 return log_error_errno(errno, "Failed to read from /dev/kmsg: %m");
@@ -349,11 +362,10 @@ int server_flush_dev_kmsg(Server *s) {
 }
 
 static int dispatch_dev_kmsg(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
-        Server *s = userdata;
+        Server *s = ASSERT_PTR(userdata);
 
         assert(es);
         assert(fd == s->dev_kmsg_fd);
-        assert(s);
 
         if (revents & EPOLLERR)
                 log_warning("/dev/kmsg buffer overrun, some messages lost.");