journald-kmsg.c revision 15a5e95075a7f6007dd97b2a165c8ed16fe683df
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 <fcntl.h>
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include <sys/epoll.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <sys/mman.h>
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <sys/socket.h>
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include <unistd.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "libudev.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "sd-messages.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "escape.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "formats-util.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "io-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "journald-kmsg.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "journald-server.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering#include "journald-syslog.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier#include "process-util.h"
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poettering#include "stdio-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.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,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct ucred *ucred) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct iovec iovec[5];
3b97fcbd28f92a1e51887fef5de8844a89bde523Lennart Poettering char header_priority[DECIMAL_STR_MAX(priority) + 3],
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1];
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 */
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek xsprintf(header_priority, "<%i>", 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
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek xsprintf(header_pid, "["PID_FMT"]: ", ucred->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)
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_debug_errno(errno, "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
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poetteringstatic void dev_kmsg_record(Server *s, const 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",
b9c488f60050248b35640f28e4d00958702ba1c3Eelco Dolstra serial - *s->kernel_seqnum);
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;
dc61b7e45d89a69f0469ab7b3289cdde7fcc55abTorstein Husebø /* Metadata 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
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering if (cunescape_length_with_prefix(k, e - k, "_KERNEL_", UNESCAPE_RELAX, &m) < 0)
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
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar IOVEC_SET_STRING(iovec[n++], syslog_facility);
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar
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
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0)
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
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "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
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to add /dev/kmsg fd to event loop: %m");
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) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to adjust priority of kmsg event source: %m");
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:
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering return r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint server_open_kernel_seqnum(Server *s) {
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering _cleanup_close_ 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) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "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) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Failed to allocate sequential number file, ignoring: %m");
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) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Failed to map sequential number file, ignoring: %m");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering s->kernel_seqnum = p;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}