-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <sys/epoll.h>
#include "escape.h"
#include "fd-util.h"
#include "format-util.h"
+#include "fs-util.h"
#include "io-util.h"
#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"
/* Second: identifier and PID */
if (ucred) {
if (!identifier) {
- get_process_comm(ucred->pid, &ident_buf);
+ (void) get_process_comm(ucred->pid, &ident_buf);
identifier = ident_buf;
}
char *e, *f, *k;
uint64_t serial;
size_t pl;
+ int saved_log_max_level = INT_MAX;
+ ClientContext *c = NULL;
assert(s);
assert(p);
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);
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++)
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");
}
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.");
s->dev_kmsg_fd = open("/dev/kmsg", mode);
if (s->dev_kmsg_fd < 0) {
- log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
- "Failed to open /dev/kmsg, ignoring: %m");
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
+ errno, "Failed to open /dev/kmsg, ignoring: %m");
return 0;
}
return 0;
}
- r = posix_fallocate(fd, 0, sizeof(uint64_t));
- if (r != 0) {
+ r = posix_fallocate_loop(fd, 0, sizeof(uint64_t));
+ if (r < 0) {
log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m");
return 0;
}