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