journald-kmsg.c revision 0b452006de98294d1690f045f6ea2f7f6630ec3b
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering/***
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering This file is part of systemd.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering Copyright 2011 Lennart Poettering
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering systemd is free software; you can redistribute it and/or modify it
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering under the terms of the GNU Lesser General Public License as published by
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering (at your option) any later version.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering systemd is distributed in the hope that it will be useful, but
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering Lesser General Public License for more details.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering You should have received a copy of the GNU Lesser General Public License
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering***/
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <unistd.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <sys/epoll.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <fcntl.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <sys/mman.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <sys/socket.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen#include "systemd/sd-messages.h"
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen#include <libudev.h>
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "journald-server.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "journald-kmsg.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "journald-syslog.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "formats-util.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "process-util.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringvoid server_forward_kmsg(
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering Server *s,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering int priority,
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallace const char *identifier,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering const char *message,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const struct ucred *ucred) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering struct iovec iovec[5];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering char header_priority[DECIMAL_STR_MAX(priority) + 3],
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering int n = 0;
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer char *ident_buf = NULL;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(priority >= 0);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(priority <= 999);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(message);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (_unlikely_(LOG_PRI(priority) > s->max_level_kmsg))
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering if (_unlikely_(s->dev_kmsg_fd < 0))
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering return;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* Never allow messages with kernel facility to be written to
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * kmsg, regardless where the data comes from. */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering priority = syslog_fixup_facility(priority);
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers /* First: priority field */
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers xsprintf(header_priority, "<%i>", priority);
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers IOVEC_SET_STRING(iovec[n++], header_priority);
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers /* Second: identifier and PID */
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (ucred) {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (!identifier) {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers get_process_comm(ucred->pid, &ident_buf);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering identifier = ident_buf;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sievers xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (identifier)
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden IOVEC_SET_STRING(iovec[n++], identifier);
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], header_pid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering } else if (identifier) {
599659860c770058f2eb04d578c521c16e0b1853Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
599659860c770058f2eb04d578c521c16e0b1853Lennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering }
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering /* Fourth: message */
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering IOVEC_SET_STRING(iovec[n++], message);
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers IOVEC_SET_STRING(iovec[n++], "\n");
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering if (writev(s->dev_kmsg_fd, iovec, n) < 0)
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering log_debug_errno(errno, "Failed to write to /dev/kmsg for logging: %m");
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering free(ident_buf);
3e5e74d5b7f6fcbeff7b6e4e06abd931aab14c48Shawn Landden}
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landdenstatic bool is_us(const char *pid) {
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden pid_t t;
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden assert(pid);
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden if (parse_pid(pid, &t) < 0)
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering return false;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden return t == getpid();
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek}
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmekstatic void dev_kmsg_record(Server *s, const char *p, size_t l) {
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden int priority, r;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden unsigned n = 0, z = 0, j;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden unsigned long long usec;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden char *identifier = NULL, *pid = NULL, *e, *f, *k;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering uint64_t serial;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers size_t pl;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers char *kernel_device = NULL;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering assert(s);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek assert(p);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (l <= 0)
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden return;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek e = memchr(p, ',', l);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek if (!e)
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen return;
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering *e = 0;
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering r = safe_atoi(p, &priority);
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering if (r < 0 || priority < 0 || priority > 999)
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering return;
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering return;
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering
d95a74ed1191bb09f5be57b0619d3d77708e019dLennart Poettering l -= (e - p) + 1;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek p = e + 1;
2fc4f5bd924b9732afc70f8a6da80573f833fc9dLennart Poettering e = memchr(p, ',', l);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (!e)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek *e = 0;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers r = safe_atou64(p, &serial);
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (r < 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (s->kernel_seqnum) {
c264aeab4b0e7b69f469e12e78d4a48b3ed7a66eKay Sievers /* We already read this one? */
c264aeab4b0e7b69f469e12e78d4a48b3ed7a66eKay Sievers if (serial < *s->kernel_seqnum)
c264aeab4b0e7b69f469e12e78d4a48b3ed7a66eKay Sievers return;
c264aeab4b0e7b69f469e12e78d4a48b3ed7a66eKay Sievers
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John /* Did we lose any? */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (serial > *s->kernel_seqnum)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen serial - *s->kernel_seqnum);
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* Make sure we never read this one again. Note that
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * we always store the next message serial we expect
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * here, simply because this makes handling the first
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * message with serial 0 easy. */
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers *s->kernel_seqnum = serial + 1;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers l -= (e - p) + 1;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers p = e + 1;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers f = memchr(p, ';', l);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers if (!f)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering e = memchr(p, ',', l);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers if (!e || f < e)
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers e = f;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers *e = 0;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = safe_atollu(p, &usec);
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering l -= (f - p) + 1;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering p = f + 1;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering e = memchr(p, '\n', l);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers if (!e)
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers return;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers *e = 0;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering pl = e - p;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering l -= (e - p) + 1;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen k = e + 1;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering char *m;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* Meta data fields attached */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (*k != ' ')
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering break;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering k ++, l --;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering e = memchr(k, '\n', l);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (!e)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering *e = 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (cunescape_length_with_prefix(k, e - k, "_KERNEL_", UNESCAPE_RELAX, &m) < 0)
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen break;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (startswith(m, "_KERNEL_DEVICE="))
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen kernel_device = m + 15;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen IOVEC_SET_STRING(iovec[n++], m);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen z++;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen l -= (e - k) + 1;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen k = e + 1;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (kernel_device) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen struct udev_device *ud;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen ud = udev_device_new_from_device_id(s->udev, kernel_device);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (ud) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const char *g;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering struct udev_list_entry *ll;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering char *b;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering g = udev_device_get_devnode(ud);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (g) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen b = strappend("_UDEV_DEVNODE=", g);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (b) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen IOVEC_SET_STRING(iovec[n++], b);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen z++;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen g = udev_device_get_sysname(ud);
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John if (g) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen b = strappend("_UDEV_SYSNAME=", g);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (b) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], b);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering z++;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering j = 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering ll = udev_device_get_devlinks_list_entry(ud);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering udev_list_entry_foreach(ll, ll) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (j > N_IOVEC_UDEV_FIELDS)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering break;
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering g = udev_list_entry_get_name(ll);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (g) {
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering b = strappend("_UDEV_DEVLINK=", g);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (b) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], b);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen z++;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen j++;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering udev_device_unref(ud);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], source_time);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel");
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if ((priority & LOG_FACMASK) == LOG_KERN)
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering else {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* Avoid any messages we generated ourselves via
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * log_info() and friends. */
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (pid && is_us(pid))
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen goto finish;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (identifier) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (syslog_identifier)
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen IOVEC_SET_STRING(iovec[n++], syslog_identifier);
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (pid) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen syslog_pid = strappend("SYSLOG_PID=", pid);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen if (syslog_pid)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_pid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering IOVEC_SET_STRING(iovec[n++], message);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority, 0);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
7568345034f2890af745747783c5abfbf6eccf0fLennart Poetteringfinish:
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt for (j = 0; j < z; j++)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt free(iovec[j].iov_base);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering free(message);
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen free(syslog_priority);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering free(syslog_identifier);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering free(syslog_pid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering free(syslog_facility);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering free(source_time);
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek free(identifier);
7591abd48079edc1f2adbd922e4b83eb73abeabeLennart Poettering free(pid);
7591abd48079edc1f2adbd922e4b83eb73abeabeLennart Poettering}
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmekstatic int server_read_dev_kmsg(Server *s) {
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek char buffer[8192+1]; /* the kernel-side limit per record is 8K currently */
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek ssize_t l;
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek assert(s);
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek assert(s->dev_kmsg_fd >= 0);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek l = read(s->dev_kmsg_fd, buffer, sizeof(buffer) - 1);
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek if (l == 0)
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John return 0;
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John if (l < 0) {
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek /* Old kernels who don't allow reading from /dev/kmsg
3906ab4adf0aa7b952e39100262a11acd55cd79bRonny Chevalier * return EINVAL when we try. So handle this cleanly,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * but don' try to ever read from it again. */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (errno == EINVAL) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
c978343015c787713651dff571acb5207367f5f2Lennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(errno, "Failed to read from kernel: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return -errno;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
c978343015c787713651dff571acb5207367f5f2Lennart Poettering dev_kmsg_record(s, buffer, l);
c978343015c787713651dff571acb5207367f5f2Lennart Poettering return 1;
c978343015c787713651dff571acb5207367f5f2Lennart Poettering}
c978343015c787713651dff571acb5207367f5f2Lennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersenint server_flush_dev_kmsg(Server *s) {
c978343015c787713651dff571acb5207367f5f2Lennart Poettering int r;
c978343015c787713651dff571acb5207367f5f2Lennart Poettering
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering assert(s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (s->dev_kmsg_fd < 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (!s->dev_kmsg_readable)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek log_debug("Flushing /dev/kmsg...");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering for (;;) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering r = server_read_dev_kmsg(s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (r < 0)
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return r;
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (r == 0)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering break;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering}
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersenstatic int dispatch_dev_kmsg(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen Server *s = userdata;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(es);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen assert(fd == s->dev_kmsg_fd);
de33fc625725d199629ed074d6278504deb23debLennart Poettering assert(s);
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (revents & EPOLLERR)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_warning("/dev/kmsg buffer overrun, some messages lost.");
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen if (!(revents & EPOLLIN))
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen log_error("Got invalid event from epoll for /dev/kmsg: %"PRIx32, revents);
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen
c978343015c787713651dff571acb5207367f5f2Lennart Poettering return server_read_dev_kmsg(s);
c978343015c787713651dff571acb5207367f5f2Lennart Poettering}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringint server_open_dev_kmsg(Server *s) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering int r;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (s->dev_kmsg_fd < 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering "Failed to open /dev/kmsg, ignoring: %m");
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (r < 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen /* This will fail with EPERM on older kernels where
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * /dev/kmsg is not readable. */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (r == -EPERM) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering r = 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering goto fail;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(r, "Failed to add /dev/kmsg fd to event loop: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering goto fail;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (r < 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(r, "Failed to adjust priority of kmsg event source: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering goto fail;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->dev_kmsg_readable = true;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringfail:
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return r;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringint server_open_kernel_seqnum(Server *s) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering _cleanup_close_ int fd;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering uint64_t *p;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert(s);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* We store the seqnum we last read in an mmaped file. That
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * way we can just use it like a variable, but it is
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * persistent and automatically flushed at reboot. */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (fd < 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(errno, "Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (posix_fallocate(fd, 0, sizeof(uint64_t)) < 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(errno, "Failed to allocate sequential number file, ignoring: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (p == MAP_FAILED) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_error_errno(errno, "Failed to map sequential number file, ignoring: %m");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering s->kernel_seqnum = p;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering return 0;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering