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