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