journald-kmsg.c revision 968f319679d9069af037240d0c3bcd126181cdac
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog This file is part of systemd.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Copyright 2011 Lennart Poettering
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is free software; you can redistribute it and/or modify it
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog under the terms of the GNU Lesser General Public License as published by
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog the Free Software Foundation; either version 2.1 of the License, or
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog (at your option) any later version.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is distributed in the hope that it will be useful, but
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog WITHOUT ANY WARRANTY; without even the implied warranty of
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Lesser General Public License for more details.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog You should have received a copy of the GNU Lesser General Public License
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog along with systemd; If not, see <http://www.gnu.org/licenses/>.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog char header_priority[6], header_pid[16];
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (_unlikely_(LOG_PRI(priority) > s->max_level_kmsg))
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Never allow messages with kernel facility to be written to
996d16975b4d802335188a3be2bbc3635c1287f3Tom Gundersen * kmsg, regardless where the data comes from. */
996d16975b4d802335188a3be2bbc3635c1287f3Tom Gundersen /* First: priority field */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog IOVEC_SET_STRING(iovec[n++], header_priority);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Second: identifier and PID */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog get_process_comm(ucred->pid, &ident_buf);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog IOVEC_SET_STRING(iovec[n++], identifier);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Fourth: message */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic void dev_kmsg_record(Server *s, char *p, size_t l) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog unsigned n = 0, z = 0, j;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog unsigned long long usec;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog char *identifier = NULL, *pid = NULL, *e, *f, *k;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (r < 0 || priority < 0 || priority > 999)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog l -= (e - p) + 1;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* We already read this one? */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Did we lose any? */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages",
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Make sure we never read this one again. Note that
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * we always store the next message serial we expect
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * here, simply because this makes handling the first
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * message with serial 0 easy. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog l -= (e - p) + 1;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (!e || f < e)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog l -= (f - p) + 1;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog l -= (e - p) + 1;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Meta data fields attached */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog m = cunescape_length_with_prefix(k, e - k, "_KERNEL_");
if (kernel_device) {
if (ud) {
if (j > N_IOVEC_UDEV_FIELDS)
goto finish;
if (identifier) {
if (syslog_identifier)
if (pid) {
if (syslog_pid)
if (message)
ssize_t l;
assert(s);
return -errno;
assert(s);
if (s->dev_kmsg_fd < 0)
if (!s->dev_kmsg_readable)
r = server_read_dev_kmsg(s);
assert(s);
if (s->dev_kmsg_fd < 0) {
return -errno;
s->dev_kmsg_readable = true;
int fd;
uint64_t *p;
assert(s);
fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
if (fd < 0) {
if (p == MAP_FAILED) {
s->kernel_seqnum = p;