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