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