journald-kmsg.c revision b2e6df73aa508cc09b1b536a2fb9f90f152b89fa
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
73f860db9893deab6aebceb53dd7d0deb662e832Zbigniew Jędrzejewski-Szmek#include <systemd/sd-messages.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <libudev.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "journald.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,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering struct ucred *ucred) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct iovec iovec[5];
3b97fcbd28f92a1e51887fef5de8844a89bde523Lennart Poettering char header_priority[6], header_pid[16];
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek 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);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek 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
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek 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
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt if (writev(s->dev_kmsg_fd, iovec, n) < 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno));
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}
3b3154df7e2773332bb814e167187367a0ccae4aLennart 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;
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering unsigned n = 0, z = 0, j;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering usec_t 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? */
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek if (serial > *s->kernel_seqnum)
b9c488f60050248b35640f28e4d00958702ba1c3Eelco Dolstra server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %llu kernel messages", (unsigned long long) 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 = parse_usec(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
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart 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);
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek b = strappend("_UDEV_DEVLINK=", g);
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek if (g) {
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], b);
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek z++;
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering j++;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering udev_device_unref(ud);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu",
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering (unsigned long long) 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 ((priority & LOG_FACMASK) == LOG_KERN)
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar else {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering syslog_parse_identifier((const char**) &p, &identifier, &pid);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Avoid any messages we generated ourselves via
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek * 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
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering message = cunescape_length_with_prefix(p, pl, "MESSAGE=");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (message)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering IOVEC_SET_STRING(iovec[n++], message);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority);
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}
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint 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. */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (errno == EINVAL) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering epoll_ctl(s->epoll_fd, EPOLL_CTL_DEL, s->dev_kmsg_fd, NULL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
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;
2b43f939a4b3ad5aeb2650868b0234ff42ec0045Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart 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}
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringint server_open_dev_kmsg(Server *s) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering struct epoll_event ev;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering assert(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (s->dev_kmsg_fd < 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_warning("Failed to open /dev/kmsg, ignoring: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering zero(ev);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering ev.events = EPOLLIN;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering ev.data.fd = s->dev_kmsg_fd;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->dev_kmsg_fd, &ev) < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* This will fail with EPERM on older kernels where
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * /dev/kmsg is not readable. */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (errno == EPERM)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("Failed to add /dev/kmsg fd to epoll object: %m");
445ea9be520b9549aee45d0b6427cf48b446987fLennart Poettering return -errno;
445ea9be520b9549aee45d0b6427cf48b446987fLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering s->dev_kmsg_readable = true;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint server_open_kernel_seqnum(Server *s) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int fd;
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering uint64_t *p;
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering assert(s);
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* We store the seqnum we last read in an mmaped file. That
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt * way we can just use it like a variable, but it is
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering * persistent and automatically flushed at reboot. */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (fd < 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m");
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return 0;
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart 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;
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering }
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering if (p == MAP_FAILED) {
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering log_error("Failed to map sequential number file, ignoring: %m");
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering close_nointr_nofail(fd);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering close_nointr_nofail(fd);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering s->kernel_seqnum = p;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering