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