]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/log.c
log: Log when kmsg is being ratelimited
[thirdparty/systemd.git] / src / basic / log.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <inttypes.h>
6 #include <limits.h>
7 #include <stdarg.h>
8 #include <stddef.h>
9 #include <sys/signalfd.h>
10 #include <sys/stat.h>
11 #include <sys/time.h>
12 #include <sys/uio.h>
13 #include <sys/un.h>
14 #include <unistd.h>
15
16 #include "sd-messages.h"
17
18 #include "alloc-util.h"
19 #include "argv-util.h"
20 #include "env-util.h"
21 #include "errno-util.h"
22 #include "fd-util.h"
23 #include "format-util.h"
24 #include "io-util.h"
25 #include "log.h"
26 #include "macro.h"
27 #include "missing_syscall.h"
28 #include "missing_threads.h"
29 #include "parse-util.h"
30 #include "proc-cmdline.h"
31 #include "process-util.h"
32 #include "ratelimit.h"
33 #include "signal-util.h"
34 #include "socket-util.h"
35 #include "stdio-util.h"
36 #include "string-table.h"
37 #include "string-util.h"
38 #include "strv.h"
39 #include "syslog-util.h"
40 #include "terminal-util.h"
41 #include "time-util.h"
42 #include "utf8.h"
43
44 #define SNDBUF_SIZE (8*1024*1024)
45 #define IOVEC_MAX 256U
46
47 static log_syntax_callback_t log_syntax_callback = NULL;
48 static void *log_syntax_callback_userdata = NULL;
49
50 static LogTarget log_target = LOG_TARGET_CONSOLE;
51 static int log_max_level = LOG_INFO;
52 static int log_facility = LOG_DAEMON;
53 static bool ratelimit_kmsg = true;
54
55 static int console_fd = STDERR_FILENO;
56 static int syslog_fd = -EBADF;
57 static int kmsg_fd = -EBADF;
58 static int journal_fd = -EBADF;
59
60 static bool syslog_is_stream = false;
61
62 static int show_color = -1; /* tristate */
63 static bool show_location = false;
64 static bool show_time = false;
65 static bool show_tid = false;
66
67 static bool upgrade_syslog_to_journal = false;
68 static bool always_reopen_console = false;
69 static bool open_when_needed = false;
70 static bool prohibit_ipc = false;
71
72 /* Akin to glibc's __abort_msg; which is private and we hence cannot
73 * use here. */
74 static char *log_abort_msg = NULL;
75
76 typedef struct LogContext {
77 unsigned n_ref;
78 /* Depending on which destructor is used (log_context_free() or log_context_detach()) the memory
79 * referenced by this is freed or not */
80 char **fields;
81 struct iovec *input_iovec;
82 size_t n_input_iovec;
83 char *key;
84 char *value;
85 bool owned;
86 LIST_FIELDS(struct LogContext, ll);
87 } LogContext;
88
89 static thread_local LIST_HEAD(LogContext, _log_context) = NULL;
90 static thread_local size_t _log_context_num_fields = 0;
91
92 static thread_local const char *log_prefix = NULL;
93
94 #if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
95 bool _log_message_dummy = false; /* Always false */
96 #endif
97
98 /* An assert to use in logging functions that does not call recursively
99 * into our logging functions (since that might lead to a loop). */
100 #define assert_raw(expr) \
101 do { \
102 if (_unlikely_(!(expr))) { \
103 fputs(#expr "\n", stderr); \
104 abort(); \
105 } \
106 } while (false)
107
108 static void log_close_console(void) {
109 console_fd = safe_close_above_stdio(console_fd);
110 }
111
112 static int log_open_console(void) {
113
114 if (!always_reopen_console) {
115 console_fd = STDERR_FILENO;
116 return 0;
117 }
118
119 if (console_fd < 3) {
120 int fd;
121
122 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
123 if (fd < 0)
124 return fd;
125
126 console_fd = fd_move_above_stdio(fd);
127 }
128
129 return 0;
130 }
131
132 static void log_close_kmsg(void) {
133 kmsg_fd = safe_close(kmsg_fd);
134 }
135
136 static int log_open_kmsg(void) {
137
138 if (kmsg_fd >= 0)
139 return 0;
140
141 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
142 if (kmsg_fd < 0)
143 return -errno;
144
145 kmsg_fd = fd_move_above_stdio(kmsg_fd);
146 return 0;
147 }
148
149 static void log_close_syslog(void) {
150 syslog_fd = safe_close(syslog_fd);
151 }
152
153 static int create_log_socket(int type) {
154 struct timeval tv;
155 int fd;
156
157 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
158 if (fd < 0)
159 return -errno;
160
161 fd = fd_move_above_stdio(fd);
162 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
163
164 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
165 * in the unlikely case of a deadlock. */
166 if (getpid_cached() == 1)
167 timeval_store(&tv, 10 * USEC_PER_MSEC);
168 else
169 timeval_store(&tv, 10 * USEC_PER_SEC);
170 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
171
172 return fd;
173 }
174
175 static int log_open_syslog(void) {
176 int r;
177
178 if (syslog_fd >= 0)
179 return 0;
180
181 syslog_fd = create_log_socket(SOCK_DGRAM);
182 if (syslog_fd < 0) {
183 r = syslog_fd;
184 goto fail;
185 }
186
187 r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
188 if (r < 0) {
189 safe_close(syslog_fd);
190
191 /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can
192 * we do... */
193 syslog_fd = create_log_socket(SOCK_STREAM);
194 if (syslog_fd < 0) {
195 r = syslog_fd;
196 goto fail;
197 }
198
199 r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log");
200 if (r < 0)
201 goto fail;
202
203 syslog_is_stream = true;
204 } else
205 syslog_is_stream = false;
206
207 return 0;
208
209 fail:
210 log_close_syslog();
211 return r;
212 }
213
214 static void log_close_journal(void) {
215 journal_fd = safe_close(journal_fd);
216 }
217
218 static int log_open_journal(void) {
219 int r;
220
221 if (journal_fd >= 0)
222 return 0;
223
224 journal_fd = create_log_socket(SOCK_DGRAM);
225 if (journal_fd < 0) {
226 r = journal_fd;
227 goto fail;
228 }
229
230 r = connect_unix_path(journal_fd, AT_FDCWD, "/run/systemd/journal/socket");
231 if (r < 0)
232 goto fail;
233
234 return 0;
235
236 fail:
237 log_close_journal();
238 return r;
239 }
240
241 static bool stderr_is_journal(void) {
242 _cleanup_free_ char *w = NULL;
243 const char *e;
244 uint64_t dev, ino;
245 struct stat st;
246
247 e = getenv("JOURNAL_STREAM");
248 if (!e)
249 return false;
250
251 if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
252 return false;
253 if (!e)
254 return false;
255
256 if (safe_atou64(w, &dev) < 0)
257 return false;
258 if (safe_atou64(e, &ino) < 0)
259 return false;
260
261 if (fstat(STDERR_FILENO, &st) < 0)
262 return false;
263
264 return st.st_dev == dev && st.st_ino == ino;
265 }
266
267 int log_open(void) {
268 int r;
269
270 /* Do not call from library code. */
271
272 /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
273 * so that a call to a logging function immediately following a log_open() call can still easily
274 * reference an error that happened immediately before the log_open() call. */
275 PROTECT_ERRNO;
276
277 /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
278 * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
279 * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
280 * because there is no reason to close it. */
281
282 if (log_target == LOG_TARGET_NULL) {
283 log_close_journal();
284 log_close_syslog();
285 log_close_console();
286 return 0;
287 }
288
289 if (getpid_cached() == 1 ||
290 stderr_is_journal() ||
291 IN_SET(log_target,
292 LOG_TARGET_KMSG,
293 LOG_TARGET_JOURNAL,
294 LOG_TARGET_JOURNAL_OR_KMSG,
295 LOG_TARGET_SYSLOG,
296 LOG_TARGET_SYSLOG_OR_KMSG)) {
297
298 if (!prohibit_ipc) {
299 if (IN_SET(log_target,
300 LOG_TARGET_AUTO,
301 LOG_TARGET_JOURNAL_OR_KMSG,
302 LOG_TARGET_JOURNAL)) {
303
304 r = log_open_journal();
305 if (r >= 0) {
306 log_close_syslog();
307 log_close_console();
308 return r;
309 }
310 }
311
312 if (IN_SET(log_target,
313 LOG_TARGET_SYSLOG_OR_KMSG,
314 LOG_TARGET_SYSLOG)) {
315
316 r = log_open_syslog();
317 if (r >= 0) {
318 log_close_journal();
319 log_close_console();
320 return r;
321 }
322 }
323 }
324
325 if (IN_SET(log_target, LOG_TARGET_AUTO,
326 LOG_TARGET_JOURNAL_OR_KMSG,
327 LOG_TARGET_SYSLOG_OR_KMSG,
328 LOG_TARGET_KMSG)) {
329 r = log_open_kmsg();
330 if (r >= 0) {
331 log_close_journal();
332 log_close_syslog();
333 log_close_console();
334 return r;
335 }
336 }
337 }
338
339 log_close_journal();
340 log_close_syslog();
341
342 return log_open_console();
343 }
344
345 void log_set_target(LogTarget target) {
346 assert(target >= 0);
347 assert(target < _LOG_TARGET_MAX);
348
349 if (upgrade_syslog_to_journal) {
350 if (target == LOG_TARGET_SYSLOG)
351 target = LOG_TARGET_JOURNAL;
352 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
353 target = LOG_TARGET_JOURNAL_OR_KMSG;
354 }
355
356 log_target = target;
357 }
358
359 void log_set_target_and_open(LogTarget target) {
360 log_set_target(target);
361 log_open();
362 }
363
364 void log_close(void) {
365 /* Do not call from library code. */
366
367 log_close_journal();
368 log_close_syslog();
369 log_close_kmsg();
370 log_close_console();
371 }
372
373 void log_forget_fds(void) {
374 /* Do not call from library code. */
375
376 console_fd = kmsg_fd = syslog_fd = journal_fd = -EBADF;
377 }
378
379 void log_set_max_level(int level) {
380 assert(level == LOG_NULL || (level & LOG_PRIMASK) == level);
381
382 log_max_level = level;
383 }
384
385 void log_set_facility(int facility) {
386 log_facility = facility;
387 }
388
389 static int write_to_console(
390 int level,
391 int error,
392 const char *file,
393 int line,
394 const char *func,
395 const char *buffer) {
396
397 char location[256],
398 header_time[FORMAT_TIMESTAMP_MAX],
399 prefix[1 + DECIMAL_STR_MAX(int) + 2],
400 tid_string[3 + DECIMAL_STR_MAX(pid_t) + 1];
401 struct iovec iovec[11];
402 const char *on = NULL, *off = NULL;
403 size_t n = 0;
404
405 if (console_fd < 0)
406 return 0;
407
408 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
409 xsprintf(prefix, "<%i>", level);
410 iovec[n++] = IOVEC_MAKE_STRING(prefix);
411 }
412
413 if (show_time &&
414 format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
415 iovec[n++] = IOVEC_MAKE_STRING(header_time);
416 iovec[n++] = IOVEC_MAKE_STRING(" ");
417 }
418
419 if (show_tid) {
420 xsprintf(tid_string, "(" PID_FMT ") ", gettid());
421 iovec[n++] = IOVEC_MAKE_STRING(tid_string);
422 }
423
424 if (log_get_show_color())
425 get_log_colors(LOG_PRI(level), &on, &off, NULL);
426
427 if (show_location) {
428 const char *lon = "", *loff = "";
429 if (log_get_show_color()) {
430 lon = ansi_highlight_yellow4();
431 loff = ansi_normal();
432 }
433
434 (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
435 iovec[n++] = IOVEC_MAKE_STRING(location);
436 }
437
438 if (on)
439 iovec[n++] = IOVEC_MAKE_STRING(on);
440 if (log_prefix) {
441 iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
442 iovec[n++] = IOVEC_MAKE_STRING(": ");
443 }
444 iovec[n++] = IOVEC_MAKE_STRING(buffer);
445 if (off)
446 iovec[n++] = IOVEC_MAKE_STRING(off);
447 iovec[n++] = IOVEC_MAKE_STRING("\n");
448
449 if (writev(console_fd, iovec, n) < 0) {
450
451 if (errno == EIO && getpid_cached() == 1) {
452
453 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
454 * to reconnect. */
455
456 log_close_console();
457 (void) log_open_console();
458 if (console_fd < 0)
459 return 0;
460
461 if (writev(console_fd, iovec, n) < 0)
462 return -errno;
463 } else
464 return -errno;
465 }
466
467 return 1;
468 }
469
470 static int write_to_syslog(
471 int level,
472 int error,
473 const char *file,
474 int line,
475 const char *func,
476 const char *buffer) {
477
478 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
479 header_time[64],
480 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
481 time_t t;
482 struct tm tm;
483
484 if (syslog_fd < 0)
485 return 0;
486
487 xsprintf(header_priority, "<%i>", level);
488
489 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
490 if (!localtime_r(&t, &tm))
491 return -EINVAL;
492
493 if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
494 return -EINVAL;
495
496 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
497
498 struct iovec iovec[] = {
499 IOVEC_MAKE_STRING(header_priority),
500 IOVEC_MAKE_STRING(header_time),
501 IOVEC_MAKE_STRING(program_invocation_short_name),
502 IOVEC_MAKE_STRING(header_pid),
503 IOVEC_MAKE_STRING(strempty(log_prefix)),
504 IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
505 IOVEC_MAKE_STRING(buffer),
506 };
507 const struct msghdr msghdr = {
508 .msg_iov = iovec,
509 .msg_iovlen = ELEMENTSOF(iovec),
510 };
511
512 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
513 if (syslog_is_stream)
514 iovec[ELEMENTSOF(iovec) - 1].iov_len++;
515
516 for (;;) {
517 ssize_t n;
518
519 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
520 if (n < 0)
521 return -errno;
522
523 if (!syslog_is_stream)
524 break;
525
526 if (IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n))
527 break;
528 }
529
530 return 1;
531 }
532
533 static int write_to_kmsg(
534 int level,
535 int error,
536 const char *file,
537 int line,
538 const char *func,
539 const char *buffer) {
540
541 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
542 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
543 * where we log excessively, but not in a tight loop.
544 *
545 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
546 * loggers.
547 */
548 static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
549
550 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
551 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
552
553 if (kmsg_fd < 0)
554 return 0;
555
556 if (ratelimit_kmsg && !ratelimit_below(&ratelimit)) {
557 if (ratelimit_num_dropped(&ratelimit) > 1)
558 return 0;
559
560 buffer = "Too many messages being logged to kmsg, ignoring";
561 }
562
563 xsprintf(header_priority, "<%i>", level);
564 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
565
566 const struct iovec iovec[] = {
567 IOVEC_MAKE_STRING(header_priority),
568 IOVEC_MAKE_STRING(program_invocation_short_name),
569 IOVEC_MAKE_STRING(header_pid),
570 IOVEC_MAKE_STRING(strempty(log_prefix)),
571 IOVEC_MAKE_STRING(log_prefix ? ": " : ""),
572 IOVEC_MAKE_STRING(buffer),
573 IOVEC_MAKE_STRING("\n"),
574 };
575
576 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
577 return -errno;
578
579 return 1;
580 }
581
582 static int log_do_header(
583 char *header,
584 size_t size,
585 int level,
586 int error,
587 const char *file, int line, const char *func,
588 const char *object_field, const char *object,
589 const char *extra_field, const char *extra) {
590 int r;
591
592 error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
593
594 r = snprintf(header, size,
595 "PRIORITY=%i\n"
596 "SYSLOG_FACILITY=%i\n"
597 "TID=" PID_FMT "\n"
598 "%s%.256s%s" /* CODE_FILE */
599 "%s%.*i%s" /* CODE_LINE */
600 "%s%.256s%s" /* CODE_FUNC */
601 "%s%.*i%s" /* ERRNO */
602 "%s%.256s%s" /* object */
603 "%s%.256s%s" /* extra */
604 "SYSLOG_IDENTIFIER=%.256s\n",
605 LOG_PRI(level),
606 LOG_FAC(level),
607 gettid(),
608 isempty(file) ? "" : "CODE_FILE=",
609 isempty(file) ? "" : file,
610 isempty(file) ? "" : "\n",
611 line ? "CODE_LINE=" : "",
612 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
613 line ? "\n" : "",
614 isempty(func) ? "" : "CODE_FUNC=",
615 isempty(func) ? "" : func,
616 isempty(func) ? "" : "\n",
617 error ? "ERRNO=" : "",
618 error ? 1 : 0, error,
619 error ? "\n" : "",
620 isempty(object) ? "" : object_field,
621 isempty(object) ? "" : object,
622 isempty(object) ? "" : "\n",
623 isempty(extra) ? "" : extra_field,
624 isempty(extra) ? "" : extra,
625 isempty(extra) ? "" : "\n",
626 program_invocation_short_name);
627 assert_raw((size_t) r < size);
628
629 return 0;
630 }
631
632 static void log_do_context(struct iovec *iovec, size_t iovec_len, size_t *n) {
633 assert(iovec);
634 assert(n);
635
636 LIST_FOREACH(ll, c, _log_context) {
637 STRV_FOREACH(s, c->fields) {
638 if (*n + 2 >= iovec_len)
639 return;
640
641 iovec[(*n)++] = IOVEC_MAKE_STRING(*s);
642 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
643 }
644
645 for (size_t i = 0; i < c->n_input_iovec; i++) {
646 if (*n + 2 >= iovec_len)
647 return;
648
649 iovec[(*n)++] = c->input_iovec[i];
650 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
651 }
652
653 if (c->key && c->value) {
654 if (*n + 3 >= iovec_len)
655 return;
656
657 iovec[(*n)++] = IOVEC_MAKE_STRING(c->key);
658 iovec[(*n)++] = IOVEC_MAKE_STRING(c->value);
659 iovec[(*n)++] = IOVEC_MAKE_STRING("\n");
660 }
661 }
662 }
663
664 static int write_to_journal(
665 int level,
666 int error,
667 const char *file,
668 int line,
669 const char *func,
670 const char *object_field,
671 const char *object,
672 const char *extra_field,
673 const char *extra,
674 const char *buffer) {
675
676 char header[LINE_MAX];
677 size_t n = 0, iovec_len;
678 struct iovec *iovec;
679
680 if (journal_fd < 0)
681 return 0;
682
683 iovec_len = MIN(6 + _log_context_num_fields * 2, IOVEC_MAX);
684 iovec = newa(struct iovec, iovec_len);
685
686 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
687
688 iovec[n++] = IOVEC_MAKE_STRING(header);
689 iovec[n++] = IOVEC_MAKE_STRING("MESSAGE=");
690 if (log_prefix) {
691 iovec[n++] = IOVEC_MAKE_STRING(log_prefix);
692 iovec[n++] = IOVEC_MAKE_STRING(": ");
693 }
694 iovec[n++] = IOVEC_MAKE_STRING(buffer);
695 iovec[n++] = IOVEC_MAKE_STRING("\n");
696
697 log_do_context(iovec, iovec_len, &n);
698
699 const struct msghdr msghdr = {
700 .msg_iov = iovec,
701 .msg_iovlen = n,
702 };
703
704 if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) < 0)
705 return -errno;
706
707 return 1;
708 }
709
710 int log_dispatch_internal(
711 int level,
712 int error,
713 const char *file,
714 int line,
715 const char *func,
716 const char *object_field,
717 const char *object,
718 const char *extra_field,
719 const char *extra,
720 char *buffer) {
721
722 assert_raw(buffer);
723
724 if (log_target == LOG_TARGET_NULL)
725 return -ERRNO_VALUE(error);
726
727 /* Patch in LOG_DAEMON facility if necessary */
728 if ((level & LOG_FACMASK) == 0)
729 level |= log_facility;
730
731 if (open_when_needed)
732 (void) log_open();
733
734 do {
735 char *e;
736 int k = 0;
737
738 buffer += strspn(buffer, NEWLINE);
739
740 if (buffer[0] == 0)
741 break;
742
743 if ((e = strpbrk(buffer, NEWLINE)))
744 *(e++) = 0;
745
746 if (IN_SET(log_target, LOG_TARGET_AUTO,
747 LOG_TARGET_JOURNAL_OR_KMSG,
748 LOG_TARGET_JOURNAL)) {
749
750 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
751 if (k < 0 && k != -EAGAIN)
752 log_close_journal();
753 }
754
755 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
756 LOG_TARGET_SYSLOG)) {
757
758 k = write_to_syslog(level, error, file, line, func, buffer);
759 if (k < 0 && k != -EAGAIN)
760 log_close_syslog();
761 }
762
763 if (k <= 0 &&
764 IN_SET(log_target, LOG_TARGET_AUTO,
765 LOG_TARGET_SYSLOG_OR_KMSG,
766 LOG_TARGET_JOURNAL_OR_KMSG,
767 LOG_TARGET_KMSG)) {
768
769 if (k < 0)
770 log_open_kmsg();
771
772 k = write_to_kmsg(level, error, file, line, func, buffer);
773 if (k < 0) {
774 log_close_kmsg();
775 (void) log_open_console();
776 }
777 }
778
779 if (k <= 0)
780 (void) write_to_console(level, error, file, line, func, buffer);
781
782 buffer = e;
783 } while (buffer);
784
785 if (open_when_needed)
786 log_close();
787
788 return -ERRNO_VALUE(error);
789 }
790
791 int log_dump_internal(
792 int level,
793 int error,
794 const char *file,
795 int line,
796 const char *func,
797 char *buffer) {
798
799 PROTECT_ERRNO;
800
801 /* This modifies the buffer... */
802
803 if (_likely_(LOG_PRI(level) > log_max_level))
804 return -ERRNO_VALUE(error);
805
806 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
807 }
808
809 int log_internalv(
810 int level,
811 int error,
812 const char *file,
813 int line,
814 const char *func,
815 const char *format,
816 va_list ap) {
817
818 if (_likely_(LOG_PRI(level) > log_max_level))
819 return -ERRNO_VALUE(error);
820
821 /* Make sure that %m maps to the specified error (or "Success"). */
822 char buffer[LINE_MAX];
823 LOCAL_ERRNO(ERRNO_VALUE(error));
824
825 (void) vsnprintf(buffer, sizeof buffer, format, ap);
826
827 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
828 }
829
830 int log_internal(
831 int level,
832 int error,
833 const char *file,
834 int line,
835 const char *func,
836 const char *format, ...) {
837
838 va_list ap;
839 int r;
840
841 va_start(ap, format);
842 r = log_internalv(level, error, file, line, func, format, ap);
843 va_end(ap);
844
845 return r;
846 }
847
848 int log_object_internalv(
849 int level,
850 int error,
851 const char *file,
852 int line,
853 const char *func,
854 const char *object_field,
855 const char *object,
856 const char *extra_field,
857 const char *extra,
858 const char *format,
859 va_list ap) {
860
861 char *buffer, *b;
862
863 if (_likely_(LOG_PRI(level) > log_max_level))
864 return -ERRNO_VALUE(error);
865
866 /* Make sure that %m maps to the specified error (or "Success"). */
867 LOCAL_ERRNO(ERRNO_VALUE(error));
868
869 LOG_SET_PREFIX(object);
870
871 b = buffer = newa(char, LINE_MAX);
872 (void) vsnprintf(b, LINE_MAX, format, ap);
873
874 return log_dispatch_internal(level, error, file, line, func,
875 object_field, object, extra_field, extra, buffer);
876 }
877
878 int log_object_internal(
879 int level,
880 int error,
881 const char *file,
882 int line,
883 const char *func,
884 const char *object_field,
885 const char *object,
886 const char *extra_field,
887 const char *extra,
888 const char *format, ...) {
889
890 va_list ap;
891 int r;
892
893 va_start(ap, format);
894 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
895 va_end(ap);
896
897 return r;
898 }
899
900 static void log_assert(
901 int level,
902 const char *text,
903 const char *file,
904 int line,
905 const char *func,
906 const char *format) {
907
908 static char buffer[LINE_MAX];
909
910 if (_likely_(LOG_PRI(level) > log_max_level))
911 return;
912
913 DISABLE_WARNING_FORMAT_NONLITERAL;
914 (void) snprintf(buffer, sizeof buffer, format, text, file, line, func);
915 REENABLE_WARNING;
916
917 log_abort_msg = buffer;
918
919 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
920 }
921
922 _noreturn_ void log_assert_failed(
923 const char *text,
924 const char *file,
925 int line,
926 const char *func) {
927 log_assert(LOG_CRIT, text, file, line, func,
928 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
929 abort();
930 }
931
932 _noreturn_ void log_assert_failed_unreachable(
933 const char *file,
934 int line,
935 const char *func) {
936 log_assert(LOG_CRIT, "Code should not be reached", file, line, func,
937 "%s at %s:%u, function %s(). Aborting. 💥");
938 abort();
939 }
940
941 void log_assert_failed_return(
942 const char *text,
943 const char *file,
944 int line,
945 const char *func) {
946 PROTECT_ERRNO;
947 log_assert(LOG_DEBUG, text, file, line, func,
948 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
949 }
950
951 int log_oom_internal(int level, const char *file, int line, const char *func) {
952 return log_internal(level, ENOMEM, file, line, func, "Out of memory.");
953 }
954
955 int log_format_iovec(
956 struct iovec *iovec,
957 size_t iovec_len,
958 size_t *n,
959 bool newline_separator,
960 int error,
961 const char *format,
962 va_list ap) {
963
964 static const char nl = '\n';
965
966 while (format && *n + 1 < iovec_len) {
967 va_list aq;
968 char *m;
969 int r;
970
971 /* We need to copy the va_list structure,
972 * since vasprintf() leaves it afterwards at
973 * an undefined location */
974
975 errno = ERRNO_VALUE(error);
976
977 va_copy(aq, ap);
978 r = vasprintf(&m, format, aq);
979 va_end(aq);
980 if (r < 0)
981 return -EINVAL;
982
983 /* Now, jump enough ahead, so that we point to
984 * the next format string */
985 VA_FORMAT_ADVANCE(format, ap);
986
987 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
988 if (newline_separator)
989 iovec[(*n)++] = IOVEC_MAKE((char *)&nl, 1);
990
991 format = va_arg(ap, char *);
992 }
993 return 0;
994 }
995
996 int log_struct_internal(
997 int level,
998 int error,
999 const char *file,
1000 int line,
1001 const char *func,
1002 const char *format, ...) {
1003
1004 char buf[LINE_MAX];
1005 bool found = false;
1006 PROTECT_ERRNO;
1007 va_list ap;
1008
1009 if (_likely_(LOG_PRI(level) > log_max_level) ||
1010 log_target == LOG_TARGET_NULL)
1011 return -ERRNO_VALUE(error);
1012
1013 if ((level & LOG_FACMASK) == 0)
1014 level |= log_facility;
1015
1016 if (IN_SET(log_target,
1017 LOG_TARGET_AUTO,
1018 LOG_TARGET_JOURNAL_OR_KMSG,
1019 LOG_TARGET_JOURNAL)) {
1020
1021 if (open_when_needed)
1022 log_open_journal();
1023
1024 if (journal_fd >= 0) {
1025 char header[LINE_MAX];
1026 struct iovec *iovec;
1027 size_t n = 0, m, iovec_len;
1028 int r;
1029 bool fallback = false;
1030
1031 iovec_len = MIN(17 + _log_context_num_fields * 2, IOVEC_MAX);
1032 iovec = newa(struct iovec, iovec_len);
1033
1034 /* If the journal is available do structured logging.
1035 * Do not report the errno if it is synthetic. */
1036 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1037 iovec[n++] = IOVEC_MAKE_STRING(header);
1038
1039 va_start(ap, format);
1040 r = log_format_iovec(iovec, iovec_len, &n, true, error, format, ap);
1041 m = n;
1042 if (r < 0)
1043 fallback = true;
1044 else {
1045 log_do_context(iovec, iovec_len, &n);
1046
1047 const struct msghdr msghdr = {
1048 .msg_iov = iovec,
1049 .msg_iovlen = n,
1050 };
1051
1052 (void) sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL);
1053 }
1054
1055 va_end(ap);
1056 for (size_t i = 1; i < m; i += 2)
1057 free(iovec[i].iov_base);
1058
1059 if (!fallback) {
1060 if (open_when_needed)
1061 log_close();
1062
1063 return -ERRNO_VALUE(error);
1064 }
1065 }
1066 }
1067
1068 /* Fallback if journal logging is not available or didn't work. */
1069
1070 va_start(ap, format);
1071 while (format) {
1072 va_list aq;
1073
1074 errno = ERRNO_VALUE(error);
1075
1076 va_copy(aq, ap);
1077 (void) vsnprintf(buf, sizeof buf, format, aq);
1078 va_end(aq);
1079
1080 if (startswith(buf, "MESSAGE=")) {
1081 found = true;
1082 break;
1083 }
1084
1085 VA_FORMAT_ADVANCE(format, ap);
1086
1087 format = va_arg(ap, char *);
1088 }
1089 va_end(ap);
1090
1091 if (!found) {
1092 if (open_when_needed)
1093 log_close();
1094
1095 return -ERRNO_VALUE(error);
1096 }
1097
1098 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
1099 }
1100
1101 int log_struct_iovec_internal(
1102 int level,
1103 int error,
1104 const char *file,
1105 int line,
1106 const char *func,
1107 const struct iovec input_iovec[],
1108 size_t n_input_iovec) {
1109
1110 PROTECT_ERRNO;
1111
1112 if (_likely_(LOG_PRI(level) > log_max_level) ||
1113 log_target == LOG_TARGET_NULL)
1114 return -ERRNO_VALUE(error);
1115
1116 if ((level & LOG_FACMASK) == 0)
1117 level |= log_facility;
1118
1119 if (IN_SET(log_target, LOG_TARGET_AUTO,
1120 LOG_TARGET_JOURNAL_OR_KMSG,
1121 LOG_TARGET_JOURNAL) &&
1122 journal_fd >= 0) {
1123
1124 char header[LINE_MAX];
1125 struct iovec *iovec;
1126 size_t n = 0, iovec_len;
1127
1128 iovec_len = MIN(1 + n_input_iovec * 2 + _log_context_num_fields * 2, IOVEC_MAX);
1129 iovec = newa(struct iovec, iovec_len);
1130
1131 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1132
1133 iovec[n++] = IOVEC_MAKE_STRING(header);
1134 for (size_t i = 0; i < n_input_iovec; i++) {
1135 iovec[n++] = input_iovec[i];
1136 iovec[n++] = IOVEC_MAKE_STRING("\n");
1137 }
1138
1139 log_do_context(iovec, iovec_len, &n);
1140
1141 const struct msghdr msghdr = {
1142 .msg_iov = iovec,
1143 .msg_iovlen = n,
1144 };
1145
1146 if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) >= 0)
1147 return -ERRNO_VALUE(error);
1148 }
1149
1150 for (size_t i = 0; i < n_input_iovec; i++)
1151 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
1152 char *m;
1153
1154 m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
1155 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1156
1157 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1158 }
1159
1160 /* Couldn't find MESSAGE=. */
1161 return -ERRNO_VALUE(error);
1162 }
1163
1164 int log_set_target_from_string(const char *e) {
1165 LogTarget t;
1166
1167 t = log_target_from_string(e);
1168 if (t < 0)
1169 return t;
1170
1171 log_set_target(t);
1172 return 0;
1173 }
1174
1175 int log_set_max_level_from_string(const char *e) {
1176 int t;
1177
1178 t = log_level_from_string(e);
1179 if (t < 0)
1180 return t;
1181
1182 log_set_max_level(t);
1183 return 0;
1184 }
1185
1186 static int log_set_ratelimit_kmsg_from_string(const char *e) {
1187 int r;
1188
1189 r = parse_boolean(e);
1190 if (r < 0)
1191 return r;
1192
1193 ratelimit_kmsg = r;
1194 return 0;
1195 }
1196
1197 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1198
1199 /*
1200 * The systemd.log_xyz= settings are parsed by all tools, and
1201 * so is "debug".
1202 *
1203 * However, "quiet" is only parsed by PID 1, and only turns of
1204 * status output to /dev/console, but does not alter the log
1205 * level.
1206 */
1207
1208 if (streq(key, "debug") && !value)
1209 log_set_max_level(LOG_DEBUG);
1210
1211 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1212
1213 if (proc_cmdline_value_missing(key, value))
1214 return 0;
1215
1216 if (log_set_target_from_string(value) < 0)
1217 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1218
1219 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1220
1221 if (proc_cmdline_value_missing(key, value))
1222 return 0;
1223
1224 if (log_set_max_level_from_string(value) < 0)
1225 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1226
1227 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1228
1229 if (log_show_color_from_string(value ?: "1") < 0)
1230 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1231
1232 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1233
1234 if (log_show_location_from_string(value ?: "1") < 0)
1235 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1236
1237 } else if (proc_cmdline_key_streq(key, "systemd.log_tid")) {
1238
1239 if (log_show_tid_from_string(value ?: "1") < 0)
1240 log_warning("Failed to parse log tid setting '%s'. Ignoring.", value);
1241
1242 } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
1243
1244 if (log_show_time_from_string(value ?: "1") < 0)
1245 log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
1246
1247 } else if (proc_cmdline_key_streq(key, "systemd.log_ratelimit_kmsg")) {
1248
1249 if (log_set_ratelimit_kmsg_from_string(value ?: "1") < 0)
1250 log_warning("Failed to parse log ratelimit kmsg boolean '%s'. Ignoring.", value);
1251 }
1252
1253 return 0;
1254 }
1255
1256 static bool should_parse_proc_cmdline(void) {
1257 /* PID1 always reads the kernel command line. */
1258 if (getpid_cached() == 1)
1259 return true;
1260
1261 /* Otherwise, parse the commandline if invoked directly by systemd. */
1262 return invoked_by_systemd();
1263 }
1264
1265 void log_parse_environment_variables(void) {
1266 const char *e;
1267
1268 e = getenv("SYSTEMD_LOG_TARGET");
1269 if (e && log_set_target_from_string(e) < 0)
1270 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1271
1272 e = getenv("SYSTEMD_LOG_LEVEL");
1273 if (e && log_set_max_level_from_string(e) < 0)
1274 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1275
1276 e = getenv("SYSTEMD_LOG_COLOR");
1277 if (e && log_show_color_from_string(e) < 0)
1278 log_warning("Failed to parse log color '%s'. Ignoring.", e);
1279
1280 e = getenv("SYSTEMD_LOG_LOCATION");
1281 if (e && log_show_location_from_string(e) < 0)
1282 log_warning("Failed to parse log location '%s'. Ignoring.", e);
1283
1284 e = getenv("SYSTEMD_LOG_TIME");
1285 if (e && log_show_time_from_string(e) < 0)
1286 log_warning("Failed to parse log time '%s'. Ignoring.", e);
1287
1288 e = getenv("SYSTEMD_LOG_TID");
1289 if (e && log_show_tid_from_string(e) < 0)
1290 log_warning("Failed to parse log tid '%s'. Ignoring.", e);
1291
1292 e = getenv("SYSTEMD_LOG_RATELIMIT_KMSG");
1293 if (e && log_set_ratelimit_kmsg_from_string(e) < 0)
1294 log_warning("Failed to parse log ratelimit kmsg boolean '%s'. Ignoring.", e);
1295 }
1296
1297 void log_parse_environment(void) {
1298 /* Do not call from library code. */
1299
1300 if (should_parse_proc_cmdline())
1301 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1302
1303 log_parse_environment_variables();
1304 }
1305
1306 LogTarget log_get_target(void) {
1307 return log_target;
1308 }
1309
1310 void log_settle_target(void) {
1311
1312 /* If we're using LOG_TARGET_AUTO and opening the log again on every single log call, we'll check if
1313 * stderr is attached to the journal every single log call. However, if we then close all file
1314 * descriptors later, that will stop working because stderr will be closed as well. To avoid that
1315 * problem, this function is used to permanently change the log target depending on whether stderr is
1316 * connected to the journal or not. */
1317
1318 LogTarget t = log_get_target();
1319
1320 if (t != LOG_TARGET_AUTO)
1321 return;
1322
1323 t = getpid_cached() == 1 || stderr_is_journal() ? (prohibit_ipc ? LOG_TARGET_KMSG : LOG_TARGET_JOURNAL_OR_KMSG)
1324 : LOG_TARGET_CONSOLE;
1325 log_set_target(t);
1326 }
1327
1328 int log_get_max_level(void) {
1329 return log_max_level;
1330 }
1331
1332 void log_show_color(bool b) {
1333 show_color = b;
1334 }
1335
1336 bool log_get_show_color(void) {
1337 return show_color > 0; /* Defaults to false. */
1338 }
1339
1340 void log_show_location(bool b) {
1341 show_location = b;
1342 }
1343
1344 bool log_get_show_location(void) {
1345 return show_location;
1346 }
1347
1348 void log_show_time(bool b) {
1349 show_time = b;
1350 }
1351
1352 bool log_get_show_time(void) {
1353 return show_time;
1354 }
1355
1356 void log_show_tid(bool b) {
1357 show_tid = b;
1358 }
1359
1360 bool log_get_show_tid(void) {
1361 return show_tid;
1362 }
1363
1364 int log_show_color_from_string(const char *e) {
1365 int t;
1366
1367 t = parse_boolean(e);
1368 if (t < 0)
1369 return t;
1370
1371 log_show_color(t);
1372 return 0;
1373 }
1374
1375 int log_show_location_from_string(const char *e) {
1376 int t;
1377
1378 t = parse_boolean(e);
1379 if (t < 0)
1380 return t;
1381
1382 log_show_location(t);
1383 return 0;
1384 }
1385
1386 int log_show_time_from_string(const char *e) {
1387 int t;
1388
1389 t = parse_boolean(e);
1390 if (t < 0)
1391 return t;
1392
1393 log_show_time(t);
1394 return 0;
1395 }
1396
1397 int log_show_tid_from_string(const char *e) {
1398 int t;
1399
1400 t = parse_boolean(e);
1401 if (t < 0)
1402 return t;
1403
1404 log_show_tid(t);
1405 return 0;
1406 }
1407
1408 bool log_on_console(void) {
1409 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1410 LOG_TARGET_CONSOLE_PREFIXED))
1411 return true;
1412
1413 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1414 }
1415
1416 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1417 [LOG_TARGET_CONSOLE] = "console",
1418 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1419 [LOG_TARGET_KMSG] = "kmsg",
1420 [LOG_TARGET_JOURNAL] = "journal",
1421 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1422 [LOG_TARGET_SYSLOG] = "syslog",
1423 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1424 [LOG_TARGET_AUTO] = "auto",
1425 [LOG_TARGET_NULL] = "null",
1426 };
1427
1428 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1429
1430 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1431 assert(si);
1432
1433 if (pid_is_valid(si->ssi_pid)) {
1434 _cleanup_free_ char *p = NULL;
1435
1436 (void) get_process_comm(si->ssi_pid, &p);
1437
1438 log_full(level,
1439 "Received SIG%s from PID %"PRIu32" (%s).",
1440 signal_to_string(si->ssi_signo),
1441 si->ssi_pid, strna(p));
1442 } else
1443 log_full(level,
1444 "Received SIG%s.",
1445 signal_to_string(si->ssi_signo));
1446 }
1447
1448 void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
1449 assert(!log_syntax_callback || !cb);
1450 assert(!log_syntax_callback_userdata || !userdata);
1451
1452 log_syntax_callback = cb;
1453 log_syntax_callback_userdata = userdata;
1454 }
1455
1456 int log_syntax_internal(
1457 const char *unit,
1458 int level,
1459 const char *config_file,
1460 unsigned config_line,
1461 int error,
1462 const char *file,
1463 int line,
1464 const char *func,
1465 const char *format, ...) {
1466
1467 PROTECT_ERRNO;
1468
1469 if (log_syntax_callback)
1470 log_syntax_callback(unit, level, log_syntax_callback_userdata);
1471
1472 if (_likely_(LOG_PRI(level) > log_max_level) ||
1473 log_target == LOG_TARGET_NULL)
1474 return -ERRNO_VALUE(error);
1475
1476 char buffer[LINE_MAX];
1477 va_list ap;
1478 const char *unit_fmt = NULL;
1479
1480 errno = ERRNO_VALUE(error);
1481
1482 va_start(ap, format);
1483 (void) vsnprintf(buffer, sizeof buffer, format, ap);
1484 va_end(ap);
1485
1486 if (unit)
1487 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1488
1489 if (config_file) {
1490 if (config_line > 0)
1491 return log_struct_internal(
1492 level,
1493 error,
1494 file, line, func,
1495 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1496 "CONFIG_FILE=%s", config_file,
1497 "CONFIG_LINE=%u", config_line,
1498 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1499 unit_fmt, unit,
1500 NULL);
1501 else
1502 return log_struct_internal(
1503 level,
1504 error,
1505 file, line, func,
1506 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1507 "CONFIG_FILE=%s", config_file,
1508 LOG_MESSAGE("%s: %s", config_file, buffer),
1509 unit_fmt, unit,
1510 NULL);
1511 } else if (unit)
1512 return log_struct_internal(
1513 level,
1514 error,
1515 file, line, func,
1516 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1517 LOG_MESSAGE("%s: %s", unit, buffer),
1518 unit_fmt, unit,
1519 NULL);
1520 else
1521 return log_struct_internal(
1522 level,
1523 error,
1524 file, line, func,
1525 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1526 LOG_MESSAGE("%s", buffer),
1527 NULL);
1528 }
1529
1530 int log_syntax_invalid_utf8_internal(
1531 const char *unit,
1532 int level,
1533 const char *config_file,
1534 unsigned config_line,
1535 const char *file,
1536 int line,
1537 const char *func,
1538 const char *rvalue) {
1539
1540 _cleanup_free_ char *p = NULL;
1541
1542 if (rvalue)
1543 p = utf8_escape_invalid(rvalue);
1544
1545 return log_syntax_internal(unit, level, config_file, config_line,
1546 SYNTHETIC_ERRNO(EINVAL), file, line, func,
1547 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1548 }
1549
1550 void log_set_upgrade_syslog_to_journal(bool b) {
1551 upgrade_syslog_to_journal = b;
1552
1553 /* Make the change effective immediately */
1554 if (b) {
1555 if (log_target == LOG_TARGET_SYSLOG)
1556 log_target = LOG_TARGET_JOURNAL;
1557 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1558 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1559 }
1560 }
1561
1562 void log_set_always_reopen_console(bool b) {
1563 always_reopen_console = b;
1564 }
1565
1566 void log_set_open_when_needed(bool b) {
1567 open_when_needed = b;
1568 }
1569
1570 void log_set_prohibit_ipc(bool b) {
1571 prohibit_ipc = b;
1572 }
1573
1574 int log_emergency_level(void) {
1575 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1576 * then the system of the whole system is obviously affected. */
1577
1578 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
1579 }
1580
1581 int log_dup_console(void) {
1582 int copy;
1583
1584 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1585 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1586
1587 if (console_fd < 0 || console_fd >= 3)
1588 return 0;
1589
1590 copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1591 if (copy < 0)
1592 return -errno;
1593
1594 console_fd = copy;
1595 return 0;
1596 }
1597
1598 void log_setup(void) {
1599 log_set_target(LOG_TARGET_AUTO);
1600 log_parse_environment();
1601 (void) log_open();
1602 if (log_on_console() && show_color < 0)
1603 log_show_color(true);
1604 }
1605
1606 const char *_log_set_prefix(const char *prefix, bool force) {
1607 const char *old = log_prefix;
1608
1609 if (prefix || force)
1610 log_prefix = prefix;
1611
1612 return old;
1613 }
1614
1615 static int saved_log_context_enabled = -1;
1616
1617 bool log_context_enabled(void) {
1618 int r;
1619
1620 if (log_get_max_level() == LOG_DEBUG)
1621 return true;
1622
1623 if (saved_log_context_enabled >= 0)
1624 return saved_log_context_enabled;
1625
1626 r = getenv_bool_secure("SYSTEMD_ENABLE_LOG_CONTEXT");
1627 if (r < 0 && r != -ENXIO)
1628 log_debug_errno(r, "Failed to parse $SYSTEMD_ENABLE_LOG_CONTEXT, ignoring: %m");
1629
1630 saved_log_context_enabled = r > 0;
1631
1632 return saved_log_context_enabled;
1633 }
1634
1635 static LogContext* log_context_attach(LogContext *c) {
1636 assert(c);
1637
1638 _log_context_num_fields += strv_length(c->fields);
1639 _log_context_num_fields += c->n_input_iovec;
1640 _log_context_num_fields += !!c->key;
1641
1642 return LIST_PREPEND(ll, _log_context, c);
1643 }
1644
1645 static LogContext* log_context_detach(LogContext *c) {
1646 if (!c)
1647 return NULL;
1648
1649 assert(_log_context_num_fields >= strv_length(c->fields) + c->n_input_iovec +!!c->key);
1650 _log_context_num_fields -= strv_length(c->fields);
1651 _log_context_num_fields -= c->n_input_iovec;
1652 _log_context_num_fields -= !!c->key;
1653
1654 LIST_REMOVE(ll, _log_context, c);
1655 return NULL;
1656 }
1657
1658 LogContext* log_context_new(const char *key, const char *value) {
1659 assert(key);
1660 assert(endswith(key, "="));
1661 assert(value);
1662
1663 LIST_FOREACH(ll, i, _log_context)
1664 if (i->key == key && i->value == value)
1665 return log_context_ref(i);
1666
1667 LogContext *c = new(LogContext, 1);
1668 if (!c)
1669 return NULL;
1670
1671 *c = (LogContext) {
1672 .n_ref = 1,
1673 .key = (char *) key,
1674 .value = (char *) value,
1675 };
1676
1677 return log_context_attach(c);
1678 }
1679
1680 LogContext* log_context_new_strv(char **fields, bool owned) {
1681 if (!fields)
1682 return NULL;
1683
1684 LIST_FOREACH(ll, i, _log_context)
1685 if (i->fields == fields) {
1686 assert(!owned);
1687 return log_context_ref(i);
1688 }
1689
1690 LogContext *c = new(LogContext, 1);
1691 if (!c)
1692 return NULL;
1693
1694 *c = (LogContext) {
1695 .n_ref = 1,
1696 .fields = fields,
1697 .owned = owned,
1698 };
1699
1700 return log_context_attach(c);
1701 }
1702
1703 LogContext* log_context_new_iov(struct iovec *input_iovec, size_t n_input_iovec, bool owned) {
1704 if (!input_iovec || n_input_iovec == 0)
1705 return NULL;
1706
1707 LIST_FOREACH(ll, i, _log_context)
1708 if (i->input_iovec == input_iovec && i->n_input_iovec == n_input_iovec) {
1709 assert(!owned);
1710 return log_context_ref(i);
1711 }
1712
1713 LogContext *c = new(LogContext, 1);
1714 if (!c)
1715 return NULL;
1716
1717 *c = (LogContext) {
1718 .n_ref = 1,
1719 .input_iovec = input_iovec,
1720 .n_input_iovec = n_input_iovec,
1721 .owned = owned,
1722 };
1723
1724 return log_context_attach(c);
1725 }
1726
1727 static LogContext* log_context_free(LogContext *c) {
1728 if (!c)
1729 return NULL;
1730
1731 log_context_detach(c);
1732
1733 if (c->owned) {
1734 strv_free(c->fields);
1735 iovec_array_free(c->input_iovec, c->n_input_iovec);
1736 free(c->key);
1737 free(c->value);
1738 }
1739
1740 return mfree(c);
1741 }
1742
1743 DEFINE_TRIVIAL_REF_UNREF_FUNC(LogContext, log_context, log_context_free);
1744
1745 LogContext* log_context_new_strv_consume(char **fields) {
1746 LogContext *c = log_context_new_strv(fields, /*owned=*/ true);
1747 if (!c)
1748 strv_free(fields);
1749
1750 return c;
1751 }
1752
1753 LogContext* log_context_new_iov_consume(struct iovec *input_iovec, size_t n_input_iovec) {
1754 LogContext *c = log_context_new_iov(input_iovec, n_input_iovec, /*owned=*/ true);
1755 if (!c)
1756 iovec_array_free(input_iovec, n_input_iovec);
1757
1758 return c;
1759 }
1760
1761 size_t log_context_num_contexts(void) {
1762 size_t n = 0;
1763
1764 LIST_FOREACH(ll, c, _log_context)
1765 n++;
1766
1767 return n;
1768 }
1769
1770 size_t log_context_num_fields(void) {
1771 return _log_context_num_fields;
1772 }