]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journald-kmsg.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / journal / journald-kmsg.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
ef63833d
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2011 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
ef63833d 21#include <fcntl.h>
4f5dd394 22#include <sys/epoll.h>
ef63833d 23#include <sys/mman.h>
4871690d 24#include <sys/socket.h>
4f5dd394 25#include <unistd.h>
ef63833d 26
b4bbcaa9 27#include "libudev.h"
4f5dd394 28#include "sd-messages.h"
ef63833d 29
e6a7ec4b 30#include "alloc-util.h"
4f5dd394 31#include "escape.h"
3ffd4af2 32#include "fd-util.h"
f97b34a6 33#include "format-util.h"
afc5dbf3 34#include "io-util.h"
3ffd4af2 35#include "journald-kmsg.h"
d025f1e4 36#include "journald-server.h"
35e2e347 37#include "journald-syslog.h"
6bedfcbb 38#include "parse-util.h"
0b452006 39#include "process-util.h"
15a5e950 40#include "stdio-util.h"
07630cea 41#include "string-util.h"
ef63833d
LP
42
43void server_forward_kmsg(
44 Server *s,
45 int priority,
46 const char *identifier,
47 const char *message,
3b3154df 48 const struct ucred *ucred) {
ef63833d 49
e6a7ec4b 50 _cleanup_free_ char *ident_buf = NULL;
ef63833d 51 struct iovec iovec[5];
3b97fcbd 52 char header_priority[DECIMAL_STR_MAX(priority) + 3],
5ffa8c81 53 header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1];
ef63833d 54 int n = 0;
ef63833d
LP
55
56 assert(s);
57 assert(priority >= 0);
58 assert(priority <= 999);
59 assert(message);
60
61 if (_unlikely_(LOG_PRI(priority) > s->max_level_kmsg))
62 return;
63
64 if (_unlikely_(s->dev_kmsg_fd < 0))
65 return;
66
67 /* Never allow messages with kernel facility to be written to
68 * kmsg, regardless where the data comes from. */
69 priority = syslog_fixup_facility(priority);
70
71 /* First: priority field */
5ffa8c81 72 xsprintf(header_priority, "<%i>", priority);
e6a7ec4b 73 iovec[n++] = IOVEC_MAKE_STRING(header_priority);
ef63833d
LP
74
75 /* Second: identifier and PID */
76 if (ucred) {
77 if (!identifier) {
78 get_process_comm(ucred->pid, &ident_buf);
79 identifier = ident_buf;
80 }
81
5ffa8c81 82 xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
ef63833d
LP
83
84 if (identifier)
e6a7ec4b 85 iovec[n++] = IOVEC_MAKE_STRING(identifier);
ef63833d 86
e6a7ec4b 87 iovec[n++] = IOVEC_MAKE_STRING(header_pid);
ef63833d 88 } else if (identifier) {
e6a7ec4b
LP
89 iovec[n++] = IOVEC_MAKE_STRING(identifier);
90 iovec[n++] = IOVEC_MAKE_STRING(": ");
ef63833d
LP
91 }
92
93 /* Fourth: message */
e6a7ec4b
LP
94 iovec[n++] = IOVEC_MAKE_STRING(message);
95 iovec[n++] = IOVEC_MAKE_STRING("\n");
ef63833d
LP
96
97 if (writev(s->dev_kmsg_fd, iovec, n) < 0)
56f64d95 98 log_debug_errno(errno, "Failed to write to /dev/kmsg for logging: %m");
ef63833d
LP
99}
100
101static bool is_us(const char *pid) {
102 pid_t t;
103
104 assert(pid);
105
106 if (parse_pid(pid, &t) < 0)
107 return false;
108
df0ff127 109 return t == getpid_cached();
ef63833d
LP
110}
111
3b3154df 112static void dev_kmsg_record(Server *s, const char *p, size_t l) {
d3070fbd 113
e6a7ec4b 114 _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL;
d3070fbd
LP
115 struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
116 char *kernel_device = NULL;
e9f600f2 117 unsigned long long usec;
d3070fbd
LP
118 size_t n = 0, z = 0, j;
119 int priority, r;
e6a7ec4b 120 char *e, *f, *k;
ef63833d
LP
121 uint64_t serial;
122 size_t pl;
ef63833d
LP
123
124 assert(s);
125 assert(p);
126
127 if (l <= 0)
128 return;
129
130 e = memchr(p, ',', l);
131 if (!e)
132 return;
133 *e = 0;
134
135 r = safe_atoi(p, &priority);
136 if (r < 0 || priority < 0 || priority > 999)
137 return;
138
139 if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
140 return;
141
142 l -= (e - p) + 1;
143 p = e + 1;
144 e = memchr(p, ',', l);
145 if (!e)
146 return;
147 *e = 0;
148
149 r = safe_atou64(p, &serial);
150 if (r < 0)
151 return;
152
153 if (s->kernel_seqnum) {
154 /* We already read this one? */
155 if (serial < *s->kernel_seqnum)
156 return;
157
158 /* Did we lose any? */
159 if (serial > *s->kernel_seqnum)
13181942 160 server_driver_message(s, 0,
2b044526 161 "MESSAGE_ID=" SD_MESSAGE_JOURNAL_MISSED_STR,
8a03c9ef
ZJS
162 LOG_MESSAGE("Missed %"PRIu64" kernel messages",
163 serial - *s->kernel_seqnum),
164 NULL);
ef63833d
LP
165
166 /* Make sure we never read this one again. Note that
167 * we always store the next message serial we expect
168 * here, simply because this makes handling the first
169 * message with serial 0 easy. */
170 *s->kernel_seqnum = serial + 1;
171 }
172
173 l -= (e - p) + 1;
174 p = e + 1;
175 f = memchr(p, ';', l);
176 if (!f)
177 return;
178 /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
179 e = memchr(p, ',', l);
180 if (!e || f < e)
181 e = f;
182 *e = 0;
183
e9f600f2 184 r = safe_atollu(p, &usec);
ef63833d
LP
185 if (r < 0)
186 return;
187
188 l -= (f - p) + 1;
189 p = f + 1;
190 e = memchr(p, '\n', l);
191 if (!e)
192 return;
193 *e = 0;
194
195 pl = e - p;
196 l -= (e - p) + 1;
197 k = e + 1;
198
199 for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
200 char *m;
dc61b7e4 201 /* Metadata fields attached */
ef63833d
LP
202
203 if (*k != ' ')
204 break;
205
313cefa1 206 k++, l--;
ef63833d
LP
207
208 e = memchr(k, '\n', l);
209 if (!e)
210 return;
211
212 *e = 0;
213
527b7a42 214 if (cunescape_length_with_prefix(k, e - k, "_KERNEL_", UNESCAPE_RELAX, &m) < 0)
ef63833d
LP
215 break;
216
217 if (startswith(m, "_KERNEL_DEVICE="))
218 kernel_device = m + 15;
219
e6a7ec4b 220 iovec[n++] = IOVEC_MAKE_STRING(m);
ef63833d
LP
221 z++;
222
223 l -= (e - k) + 1;
224 k = e + 1;
225 }
226
227 if (kernel_device) {
228 struct udev_device *ud;
229
230 ud = udev_device_new_from_device_id(s->udev, kernel_device);
231 if (ud) {
232 const char *g;
233 struct udev_list_entry *ll;
234 char *b;
235
236 g = udev_device_get_devnode(ud);
237 if (g) {
238 b = strappend("_UDEV_DEVNODE=", g);
239 if (b) {
e6a7ec4b 240 iovec[n++] = IOVEC_MAKE_STRING(b);
ef63833d
LP
241 z++;
242 }
243 }
244
245 g = udev_device_get_sysname(ud);
246 if (g) {
247 b = strappend("_UDEV_SYSNAME=", g);
248 if (b) {
e6a7ec4b 249 iovec[n++] = IOVEC_MAKE_STRING(b);
ef63833d
LP
250 z++;
251 }
252 }
253
254 j = 0;
255 ll = udev_device_get_devlinks_list_entry(ud);
256 udev_list_entry_foreach(ll, ll) {
257
258 if (j > N_IOVEC_UDEV_FIELDS)
259 break;
260
261 g = udev_list_entry_get_name(ll);
ef63833d 262 if (g) {
4b94f3b8
ZJS
263 b = strappend("_UDEV_DEVLINK=", g);
264 if (b) {
e6a7ec4b 265 iovec[n++] = IOVEC_MAKE_STRING(b);
4b94f3b8
ZJS
266 z++;
267 }
ef63833d
LP
268 }
269
270 j++;
271 }
272
273 udev_device_unref(ud);
274 }
275 }
276
e9f600f2 277 if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0)
e6a7ec4b 278 iovec[n++] = IOVEC_MAKE_STRING(source_time);
ef63833d 279
e6a7ec4b 280 iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=kernel");
ef63833d
LP
281
282 if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
e6a7ec4b 283 iovec[n++] = IOVEC_MAKE_STRING(syslog_priority);
ef63833d 284
36dd072c 285 if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
e6a7ec4b 286 iovec[n++] = IOVEC_MAKE_STRING(syslog_facility);
36dd072c 287
ef63833d 288 if ((priority & LOG_FACMASK) == LOG_KERN)
e6a7ec4b 289 iovec[n++] = IOVEC_MAKE_STRING("SYSLOG_IDENTIFIER=kernel");
ef63833d 290 else {
e88baee8 291 pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);
ef63833d
LP
292
293 /* Avoid any messages we generated ourselves via
294 * log_info() and friends. */
295 if (pid && is_us(pid))
296 goto finish;
297
298 if (identifier) {
299 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
300 if (syslog_identifier)
e6a7ec4b 301 iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier);
ef63833d
LP
302 }
303
304 if (pid) {
305 syslog_pid = strappend("SYSLOG_PID=", pid);
306 if (syslog_pid)
e6a7ec4b 307 iovec[n++] = IOVEC_MAKE_STRING(syslog_pid);
ef63833d 308 }
ef63833d
LP
309 }
310
527b7a42 311 if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0)
e6a7ec4b 312 iovec[n++] = IOVEC_MAKE_STRING(message);
ef63833d 313
22e3a02b 314 server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority, 0);
ef63833d
LP
315
316finish:
317 for (j = 0; j < z; j++)
318 free(iovec[j].iov_base);
ef63833d
LP
319}
320
f9a810be 321static int server_read_dev_kmsg(Server *s) {
ef63833d
LP
322 char buffer[8192+1]; /* the kernel-side limit per record is 8K currently */
323 ssize_t l;
324
325 assert(s);
326 assert(s->dev_kmsg_fd >= 0);
327
328 l = read(s->dev_kmsg_fd, buffer, sizeof(buffer) - 1);
329 if (l == 0)
330 return 0;
331 if (l < 0) {
332 /* Old kernels who don't allow reading from /dev/kmsg
333 * return EINVAL when we try. So handle this cleanly,
334 * but don' try to ever read from it again. */
335 if (errno == EINVAL) {
f9a810be 336 s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
ef63833d
LP
337 return 0;
338 }
339
3742095b 340 if (IN_SET(errno, EAGAIN, EINTR, EPIPE))
ef63833d
LP
341 return 0;
342
e1427b13 343 return log_error_errno(errno, "Failed to read from kernel: %m");
ef63833d
LP
344 }
345
346 dev_kmsg_record(s, buffer, l);
347 return 1;
348}
349
350int server_flush_dev_kmsg(Server *s) {
351 int r;
352
353 assert(s);
354
355 if (s->dev_kmsg_fd < 0)
356 return 0;
357
358 if (!s->dev_kmsg_readable)
359 return 0;
360
2b43f939 361 log_debug("Flushing /dev/kmsg...");
ef63833d
LP
362
363 for (;;) {
364 r = server_read_dev_kmsg(s);
365 if (r < 0)
366 return r;
367
368 if (r == 0)
369 break;
370 }
371
372 return 0;
373}
374
f9a810be
LP
375static int dispatch_dev_kmsg(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
376 Server *s = userdata;
377
378 assert(es);
379 assert(fd == s->dev_kmsg_fd);
380 assert(s);
381
382 if (revents & EPOLLERR)
383 log_warning("/dev/kmsg buffer overrun, some messages lost.");
384
385 if (!(revents & EPOLLIN))
386 log_error("Got invalid event from epoll for /dev/kmsg: %"PRIx32, revents);
387
388 return server_read_dev_kmsg(s);
389}
390
ef63833d 391int server_open_dev_kmsg(Server *s) {
b2392ff3 392 mode_t mode;
f9a810be 393 int r;
ef63833d
LP
394
395 assert(s);
396
b2392ff3
SS
397 if (s->read_kmsg)
398 mode = O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;
399 else
400 mode = O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;
401
402 s->dev_kmsg_fd = open("/dev/kmsg", mode);
ef63833d 403 if (s->dev_kmsg_fd < 0) {
445ea9be
LP
404 log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
405 "Failed to open /dev/kmsg, ignoring: %m");
ef63833d
LP
406 return 0;
407 }
408
b2392ff3
SS
409 if (!s->read_kmsg)
410 return 0;
411
151b9b96 412 r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
f9a810be 413 if (r < 0) {
ef63833d
LP
414
415 /* This will fail with EPERM on older kernels where
416 * /dev/kmsg is not readable. */
c0f71f46
LP
417 if (r == -EPERM) {
418 r = 0;
419 goto fail;
420 }
ef63833d 421
da927ba9 422 log_error_errno(r, "Failed to add /dev/kmsg fd to event loop: %m");
c0f71f46 423 goto fail;
f9a810be
LP
424 }
425
426 r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
427 if (r < 0) {
da927ba9 428 log_error_errno(r, "Failed to adjust priority of kmsg event source: %m");
c0f71f46 429 goto fail;
ef63833d
LP
430 }
431
432 s->dev_kmsg_readable = true;
433
434 return 0;
c0f71f46
LP
435
436fail:
03e334a1
LP
437 s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
438 s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);
c0f71f46
LP
439
440 return r;
ef63833d
LP
441}
442
443int server_open_kernel_seqnum(Server *s) {
03e334a1 444 _cleanup_close_ int fd;
ef63833d 445 uint64_t *p;
7bb87460 446 int r;
ef63833d
LP
447
448 assert(s);
449
450 /* We store the seqnum we last read in an mmaped file. That
451 * way we can just use it like a variable, but it is
b2e6df73 452 * persistent and automatically flushed at reboot. */
ef63833d
LP
453
454 fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
455 if (fd < 0) {
56f64d95 456 log_error_errno(errno, "Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m");
ef63833d
LP
457 return 0;
458 }
459
7bb87460
MS
460 r = posix_fallocate(fd, 0, sizeof(uint64_t));
461 if (r != 0) {
462 log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m");
ef63833d
LP
463 return 0;
464 }
465
466 p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
467 if (p == MAP_FAILED) {
56f64d95 468 log_error_errno(errno, "Failed to map sequential number file, ignoring: %m");
ef63833d
LP
469 return 0;
470 }
471
ef63833d
LP
472 s->kernel_seqnum = p;
473
474 return 0;
475}