]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/log.c
6bf6fad541ee5c05d2a2927574197f28afdae014
[thirdparty/systemd.git] / src / basic / log.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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 <stdio.h>
10 #include <sys/signalfd.h>
11 #include <sys/socket.h>
12 #include <sys/time.h>
13 #include <sys/uio.h>
14 #include <sys/un.h>
15 #include <unistd.h>
16
17 #include "sd-messages.h"
18
19 #include "alloc-util.h"
20 #include "errno-util.h"
21 #include "fd-util.h"
22 #include "format-util.h"
23 #include "io-util.h"
24 #include "log.h"
25 #include "macro.h"
26 #include "parse-util.h"
27 #include "proc-cmdline.h"
28 #include "process-util.h"
29 #include "ratelimit.h"
30 #include "signal-util.h"
31 #include "socket-util.h"
32 #include "stdio-util.h"
33 #include "string-table.h"
34 #include "string-util.h"
35 #include "syslog-util.h"
36 #include "terminal-util.h"
37 #include "time-util.h"
38 #include "utf8.h"
39
40 #define SNDBUF_SIZE (8*1024*1024)
41
42 static LogTarget log_target = LOG_TARGET_CONSOLE;
43 static int log_max_level[] = {LOG_INFO, LOG_INFO};
44 assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
45 static int log_facility = LOG_DAEMON;
46
47 static int console_fd = STDERR_FILENO;
48 static int syslog_fd = -1;
49 static int kmsg_fd = -1;
50 static int journal_fd = -1;
51
52 static bool syslog_is_stream = false;
53
54 static bool show_color = false;
55 static bool show_location = false;
56
57 static bool upgrade_syslog_to_journal = false;
58 static bool always_reopen_console = false;
59 static bool open_when_needed = false;
60 static bool prohibit_ipc = false;
61
62 /* Akin to glibc's __abort_msg; which is private and we hence cannot
63 * use here. */
64 static char *log_abort_msg = NULL;
65
66 /* An assert to use in logging functions that does not call recursively
67 * into our logging functions (since that might lead to a loop). */
68 #define assert_raw(expr) \
69 do { \
70 if (_unlikely_(!(expr))) { \
71 fputs(#expr "\n", stderr); \
72 abort(); \
73 } \
74 } while (false)
75
76 static void log_close_console(void) {
77 console_fd = safe_close_above_stdio(console_fd);
78 }
79
80 static int log_open_console(void) {
81
82 if (!always_reopen_console) {
83 console_fd = STDERR_FILENO;
84 return 0;
85 }
86
87 if (console_fd < 3) {
88 int fd;
89
90 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
91 if (fd < 0)
92 return fd;
93
94 console_fd = fd_move_above_stdio(fd);
95 }
96
97 return 0;
98 }
99
100 static void log_close_kmsg(void) {
101 kmsg_fd = safe_close(kmsg_fd);
102 }
103
104 static int log_open_kmsg(void) {
105
106 if (kmsg_fd >= 0)
107 return 0;
108
109 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
110 if (kmsg_fd < 0)
111 return -errno;
112
113 kmsg_fd = fd_move_above_stdio(kmsg_fd);
114 return 0;
115 }
116
117 static void log_close_syslog(void) {
118 syslog_fd = safe_close(syslog_fd);
119 }
120
121 static int create_log_socket(int type) {
122 struct timeval tv;
123 int fd;
124
125 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
126 if (fd < 0)
127 return -errno;
128
129 fd = fd_move_above_stdio(fd);
130 (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
131
132 /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
133 * in the unlikely case of a deadlock. */
134 if (getpid_cached() == 1)
135 timeval_store(&tv, 10 * USEC_PER_MSEC);
136 else
137 timeval_store(&tv, 10 * USEC_PER_SEC);
138 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
139
140 return fd;
141 }
142
143 static int log_open_syslog(void) {
144
145 static const union sockaddr_union sa = {
146 .un.sun_family = AF_UNIX,
147 .un.sun_path = "/dev/log",
148 };
149
150 int r;
151
152 if (syslog_fd >= 0)
153 return 0;
154
155 syslog_fd = create_log_socket(SOCK_DGRAM);
156 if (syslog_fd < 0) {
157 r = syslog_fd;
158 goto fail;
159 }
160
161 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
162 safe_close(syslog_fd);
163
164 /* Some legacy syslog systems still use stream
165 * sockets. They really shouldn't. But what can we
166 * do... */
167 syslog_fd = create_log_socket(SOCK_STREAM);
168 if (syslog_fd < 0) {
169 r = syslog_fd;
170 goto fail;
171 }
172
173 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
174 r = -errno;
175 goto fail;
176 }
177
178 syslog_is_stream = true;
179 } else
180 syslog_is_stream = false;
181
182 return 0;
183
184 fail:
185 log_close_syslog();
186 return r;
187 }
188
189 static void log_close_journal(void) {
190 journal_fd = safe_close(journal_fd);
191 }
192
193 static int log_open_journal(void) {
194
195 static const union sockaddr_union sa = {
196 .un.sun_family = AF_UNIX,
197 .un.sun_path = "/run/systemd/journal/socket",
198 };
199
200 int r;
201
202 if (journal_fd >= 0)
203 return 0;
204
205 journal_fd = create_log_socket(SOCK_DGRAM);
206 if (journal_fd < 0) {
207 r = journal_fd;
208 goto fail;
209 }
210
211 if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
212 r = -errno;
213 goto fail;
214 }
215
216 return 0;
217
218 fail:
219 log_close_journal();
220 return r;
221 }
222
223 int log_open(void) {
224 int r;
225
226 /* Do not call from library code. */
227
228 /* If we don't use the console we close it here, to not get
229 * killed by SAK. If we don't use syslog we close it here so
230 * that we are not confused by somebody deleting the socket in
231 * the fs, and to make sure we don't use it if prohibit_ipc is
232 * set. If we don't use /dev/kmsg we still keep it open,
233 * because there is no reason to close it. */
234
235 if (log_target == LOG_TARGET_NULL) {
236 log_close_journal();
237 log_close_syslog();
238 log_close_console();
239 return 0;
240 }
241
242 if (log_target != LOG_TARGET_AUTO ||
243 getpid_cached() == 1 ||
244 isatty(STDERR_FILENO) <= 0) {
245
246 if (!prohibit_ipc &&
247 IN_SET(log_target, LOG_TARGET_AUTO,
248 LOG_TARGET_JOURNAL_OR_KMSG,
249 LOG_TARGET_JOURNAL)) {
250 r = log_open_journal();
251 if (r >= 0) {
252 log_close_syslog();
253 log_close_console();
254 return r;
255 }
256 }
257
258 if (!prohibit_ipc &&
259 IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
260 LOG_TARGET_SYSLOG)) {
261 r = log_open_syslog();
262 if (r >= 0) {
263 log_close_journal();
264 log_close_console();
265 return r;
266 }
267 }
268
269 if (IN_SET(log_target, LOG_TARGET_AUTO,
270 LOG_TARGET_JOURNAL_OR_KMSG,
271 LOG_TARGET_SYSLOG_OR_KMSG,
272 LOG_TARGET_KMSG)) {
273 r = log_open_kmsg();
274 if (r >= 0) {
275 log_close_journal();
276 log_close_syslog();
277 log_close_console();
278 return r;
279 }
280 }
281 }
282
283 log_close_journal();
284 log_close_syslog();
285
286 return log_open_console();
287 }
288
289 void log_set_target(LogTarget target) {
290 assert(target >= 0);
291 assert(target < _LOG_TARGET_MAX);
292
293 if (upgrade_syslog_to_journal) {
294 if (target == LOG_TARGET_SYSLOG)
295 target = LOG_TARGET_JOURNAL;
296 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
297 target = LOG_TARGET_JOURNAL_OR_KMSG;
298 }
299
300 log_target = target;
301 }
302
303 void log_close(void) {
304 /* Do not call from library code. */
305
306 log_close_journal();
307 log_close_syslog();
308 log_close_kmsg();
309 log_close_console();
310 }
311
312 void log_forget_fds(void) {
313 /* Do not call from library code. */
314
315 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
316 }
317
318 void log_set_max_level_realm(LogRealm realm, int level) {
319 assert((level & LOG_PRIMASK) == level);
320 assert(realm < ELEMENTSOF(log_max_level));
321
322 log_max_level[realm] = level;
323 }
324
325 void log_set_facility(int facility) {
326 log_facility = facility;
327 }
328
329 static int write_to_console(
330 int level,
331 int error,
332 const char *file,
333 int line,
334 const char *func,
335 const char *buffer) {
336
337 char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
338 struct iovec iovec[6] = {};
339 const char *on = NULL, *off = NULL;
340 size_t n = 0;
341
342 if (console_fd < 0)
343 return 0;
344
345 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
346 xsprintf(prefix, "<%i>", level);
347 iovec[n++] = IOVEC_MAKE_STRING(prefix);
348 }
349
350 if (show_color)
351 get_log_colors(LOG_PRI(level), &on, &off, NULL);
352
353 if (show_location) {
354 const char *lon = "", *loff = "";
355 if (show_color) {
356 lon = ANSI_HIGHLIGHT_YELLOW4;
357 loff = ANSI_NORMAL;
358 }
359
360 (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
361 iovec[n++] = IOVEC_MAKE_STRING(location);
362 }
363
364 if (on)
365 iovec[n++] = IOVEC_MAKE_STRING(on);
366 iovec[n++] = IOVEC_MAKE_STRING(buffer);
367 if (off)
368 iovec[n++] = IOVEC_MAKE_STRING(off);
369 iovec[n++] = IOVEC_MAKE_STRING("\n");
370
371 if (writev(console_fd, iovec, n) < 0) {
372
373 if (errno == EIO && getpid_cached() == 1) {
374
375 /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
376 * to reconnect. */
377
378 log_close_console();
379 (void) log_open_console();
380 if (console_fd < 0)
381 return 0;
382
383 if (writev(console_fd, iovec, n) < 0)
384 return -errno;
385 } else
386 return -errno;
387 }
388
389 return 1;
390 }
391
392 static int write_to_syslog(
393 int level,
394 int error,
395 const char *file,
396 int line,
397 const char *func,
398 const char *buffer) {
399
400 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
401 header_time[64],
402 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
403 struct iovec iovec[5] = {};
404 struct msghdr msghdr = {
405 .msg_iov = iovec,
406 .msg_iovlen = ELEMENTSOF(iovec),
407 };
408 time_t t;
409 struct tm tm;
410
411 if (syslog_fd < 0)
412 return 0;
413
414 xsprintf(header_priority, "<%i>", level);
415
416 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
417 if (!localtime_r(&t, &tm))
418 return -EINVAL;
419
420 if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
421 return -EINVAL;
422
423 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
424
425 iovec[0] = IOVEC_MAKE_STRING(header_priority);
426 iovec[1] = IOVEC_MAKE_STRING(header_time);
427 iovec[2] = IOVEC_MAKE_STRING(program_invocation_short_name);
428 iovec[3] = IOVEC_MAKE_STRING(header_pid);
429 iovec[4] = IOVEC_MAKE_STRING(buffer);
430
431 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
432 if (syslog_is_stream)
433 iovec[4].iov_len++;
434
435 for (;;) {
436 ssize_t n;
437
438 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
439 if (n < 0)
440 return -errno;
441
442 if (!syslog_is_stream ||
443 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
444 break;
445
446 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
447 }
448
449 return 1;
450 }
451
452 static int write_to_kmsg(
453 int level,
454 int error,
455 const char *file,
456 int line,
457 const char *func,
458 const char *buffer) {
459
460 /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
461 * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
462 * where we log excessively, but not in a tight loop.
463 *
464 * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
465 * loggers.
466 */
467 static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
468
469 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
470 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
471 struct iovec iovec[5] = {};
472
473 if (kmsg_fd < 0)
474 return 0;
475
476 if (!ratelimit_below(&ratelimit))
477 return 0;
478
479 xsprintf(header_priority, "<%i>", level);
480 xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
481
482 iovec[0] = IOVEC_MAKE_STRING(header_priority);
483 iovec[1] = IOVEC_MAKE_STRING(program_invocation_short_name);
484 iovec[2] = IOVEC_MAKE_STRING(header_pid);
485 iovec[3] = IOVEC_MAKE_STRING(buffer);
486 iovec[4] = IOVEC_MAKE_STRING("\n");
487
488 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
489 return -errno;
490
491 return 1;
492 }
493
494 static int log_do_header(
495 char *header,
496 size_t size,
497 int level,
498 int error,
499 const char *file, int line, const char *func,
500 const char *object_field, const char *object,
501 const char *extra_field, const char *extra) {
502 int r;
503
504 error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
505
506 r = snprintf(header, size,
507 "PRIORITY=%i\n"
508 "SYSLOG_FACILITY=%i\n"
509 "%s%.256s%s" /* CODE_FILE */
510 "%s%.*i%s" /* CODE_LINE */
511 "%s%.256s%s" /* CODE_FUNC */
512 "%s%.*i%s" /* ERRNO */
513 "%s%.256s%s" /* object */
514 "%s%.256s%s" /* extra */
515 "SYSLOG_IDENTIFIER=%.256s\n",
516 LOG_PRI(level),
517 LOG_FAC(level),
518 isempty(file) ? "" : "CODE_FILE=",
519 isempty(file) ? "" : file,
520 isempty(file) ? "" : "\n",
521 line ? "CODE_LINE=" : "",
522 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
523 line ? "\n" : "",
524 isempty(func) ? "" : "CODE_FUNC=",
525 isempty(func) ? "" : func,
526 isempty(func) ? "" : "\n",
527 error ? "ERRNO=" : "",
528 error ? 1 : 0, error,
529 error ? "\n" : "",
530 isempty(object) ? "" : object_field,
531 isempty(object) ? "" : object,
532 isempty(object) ? "" : "\n",
533 isempty(extra) ? "" : extra_field,
534 isempty(extra) ? "" : extra,
535 isempty(extra) ? "" : "\n",
536 program_invocation_short_name);
537 assert_raw((size_t) r < size);
538
539 return 0;
540 }
541
542 static int write_to_journal(
543 int level,
544 int error,
545 const char *file,
546 int line,
547 const char *func,
548 const char *object_field,
549 const char *object,
550 const char *extra_field,
551 const char *extra,
552 const char *buffer) {
553
554 char header[LINE_MAX];
555 struct iovec iovec[4] = {};
556 struct msghdr mh = {};
557
558 if (journal_fd < 0)
559 return 0;
560
561 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
562
563 iovec[0] = IOVEC_MAKE_STRING(header);
564 iovec[1] = IOVEC_MAKE_STRING("MESSAGE=");
565 iovec[2] = IOVEC_MAKE_STRING(buffer);
566 iovec[3] = IOVEC_MAKE_STRING("\n");
567
568 mh.msg_iov = iovec;
569 mh.msg_iovlen = ELEMENTSOF(iovec);
570
571 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
572 return -errno;
573
574 return 1;
575 }
576
577 int log_dispatch_internal(
578 int level,
579 int error,
580 const char *file,
581 int line,
582 const char *func,
583 const char *object_field,
584 const char *object,
585 const char *extra_field,
586 const char *extra,
587 char *buffer) {
588
589 assert_raw(buffer);
590
591 if (log_target == LOG_TARGET_NULL)
592 return -ERRNO_VALUE(error);
593
594 /* Patch in LOG_DAEMON facility if necessary */
595 if ((level & LOG_FACMASK) == 0)
596 level |= log_facility;
597
598 if (open_when_needed)
599 (void) log_open();
600
601 do {
602 char *e;
603 int k = 0;
604
605 buffer += strspn(buffer, NEWLINE);
606
607 if (buffer[0] == 0)
608 break;
609
610 if ((e = strpbrk(buffer, NEWLINE)))
611 *(e++) = 0;
612
613 if (IN_SET(log_target, LOG_TARGET_AUTO,
614 LOG_TARGET_JOURNAL_OR_KMSG,
615 LOG_TARGET_JOURNAL)) {
616
617 k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
618 if (k < 0 && k != -EAGAIN)
619 log_close_journal();
620 }
621
622 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
623 LOG_TARGET_SYSLOG)) {
624
625 k = write_to_syslog(level, error, file, line, func, buffer);
626 if (k < 0 && k != -EAGAIN)
627 log_close_syslog();
628 }
629
630 if (k <= 0 &&
631 IN_SET(log_target, LOG_TARGET_AUTO,
632 LOG_TARGET_SYSLOG_OR_KMSG,
633 LOG_TARGET_JOURNAL_OR_KMSG,
634 LOG_TARGET_KMSG)) {
635
636 if (k < 0)
637 log_open_kmsg();
638
639 k = write_to_kmsg(level, error, file, line, func, buffer);
640 if (k < 0) {
641 log_close_kmsg();
642 (void) log_open_console();
643 }
644 }
645
646 if (k <= 0)
647 (void) write_to_console(level, error, file, line, func, buffer);
648
649 buffer = e;
650 } while (buffer);
651
652 if (open_when_needed)
653 log_close();
654
655 return -ERRNO_VALUE(error);
656 }
657
658 int log_dump_internal(
659 int level,
660 int error,
661 const char *file,
662 int line,
663 const char *func,
664 char *buffer) {
665
666 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
667 PROTECT_ERRNO;
668
669 /* This modifies the buffer... */
670
671 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
672 return -ERRNO_VALUE(error);
673
674 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
675 }
676
677 int log_internalv_realm(
678 int level,
679 int error,
680 const char *file,
681 int line,
682 const char *func,
683 const char *format,
684 va_list ap) {
685
686 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
687 char buffer[LINE_MAX];
688 PROTECT_ERRNO;
689
690 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
691 return -ERRNO_VALUE(error);
692
693 /* Make sure that %m maps to the specified error (or "Success"). */
694 errno = ERRNO_VALUE(error);
695
696 (void) vsnprintf(buffer, sizeof buffer, format, ap);
697
698 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
699 }
700
701 int log_internal_realm(
702 int level,
703 int error,
704 const char *file,
705 int line,
706 const char *func,
707 const char *format, ...) {
708
709 va_list ap;
710 int r;
711
712 va_start(ap, format);
713 r = log_internalv_realm(level, error, file, line, func, format, ap);
714 va_end(ap);
715
716 return r;
717 }
718
719 int log_object_internalv(
720 int level,
721 int error,
722 const char *file,
723 int line,
724 const char *func,
725 const char *object_field,
726 const char *object,
727 const char *extra_field,
728 const char *extra,
729 const char *format,
730 va_list ap) {
731
732 PROTECT_ERRNO;
733 char *buffer, *b;
734
735 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
736 return -ERRNO_VALUE(error);
737
738 /* Make sure that %m maps to the specified error (or "Success"). */
739 errno = ERRNO_VALUE(error);
740
741 /* Prepend the object name before the message */
742 if (object) {
743 size_t n;
744
745 n = strlen(object);
746 buffer = newa(char, n + 2 + LINE_MAX);
747 b = stpcpy(stpcpy(buffer, object), ": ");
748 } else
749 b = buffer = newa(char, LINE_MAX);
750
751 (void) vsnprintf(b, LINE_MAX, format, ap);
752
753 return log_dispatch_internal(level, error, file, line, func,
754 object_field, object, extra_field, extra, buffer);
755 }
756
757 int log_object_internal(
758 int level,
759 int error,
760 const char *file,
761 int line,
762 const char *func,
763 const char *object_field,
764 const char *object,
765 const char *extra_field,
766 const char *extra,
767 const char *format, ...) {
768
769 va_list ap;
770 int r;
771
772 va_start(ap, format);
773 r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
774 va_end(ap);
775
776 return r;
777 }
778
779 static void log_assert(
780 int level,
781 const char *text,
782 const char *file,
783 int line,
784 const char *func,
785 const char *format) {
786
787 static char buffer[LINE_MAX];
788 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
789
790 if (_likely_(LOG_PRI(level) > log_max_level[realm]))
791 return;
792
793 DISABLE_WARNING_FORMAT_NONLITERAL;
794 (void) snprintf(buffer, sizeof buffer, format, text, file, line, func);
795 REENABLE_WARNING;
796
797 log_abort_msg = buffer;
798
799 log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
800 }
801
802 _noreturn_ void log_assert_failed_realm(
803 LogRealm realm,
804 const char *text,
805 const char *file,
806 int line,
807 const char *func) {
808 (void) log_open();
809 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
810 "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
811 abort();
812 }
813
814 _noreturn_ void log_assert_failed_unreachable_realm(
815 LogRealm realm,
816 const char *text,
817 const char *file,
818 int line,
819 const char *func) {
820 (void) log_open();
821 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
822 "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
823 abort();
824 }
825
826 void log_assert_failed_return_realm(
827 LogRealm realm,
828 const char *text,
829 const char *file,
830 int line,
831 const char *func) {
832 PROTECT_ERRNO;
833 log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
834 "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
835 }
836
837 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
838 return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
839 ENOMEM, file, line, func, "Out of memory.");
840 }
841
842 int log_format_iovec(
843 struct iovec *iovec,
844 size_t iovec_len,
845 size_t *n,
846 bool newline_separator,
847 int error,
848 const char *format,
849 va_list ap) {
850
851 static const char nl = '\n';
852
853 while (format && *n + 1 < iovec_len) {
854 va_list aq;
855 char *m;
856 int r;
857
858 /* We need to copy the va_list structure,
859 * since vasprintf() leaves it afterwards at
860 * an undefined location */
861
862 errno = ERRNO_VALUE(error);
863
864 va_copy(aq, ap);
865 r = vasprintf(&m, format, aq);
866 va_end(aq);
867 if (r < 0)
868 return -EINVAL;
869
870 /* Now, jump enough ahead, so that we point to
871 * the next format string */
872 VA_FORMAT_ADVANCE(format, ap);
873
874 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
875
876 if (newline_separator) {
877 iovec[*n] = IOVEC_MAKE((char *)&nl, 1);
878 (*n)++;
879 }
880
881 format = va_arg(ap, char *);
882 }
883 return 0;
884 }
885
886 int log_struct_internal(
887 int level,
888 int error,
889 const char *file,
890 int line,
891 const char *func,
892 const char *format, ...) {
893
894 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
895 char buf[LINE_MAX];
896 bool found = false;
897 PROTECT_ERRNO;
898 va_list ap;
899
900 if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
901 log_target == LOG_TARGET_NULL)
902 return -ERRNO_VALUE(error);
903
904 if ((level & LOG_FACMASK) == 0)
905 level |= log_facility;
906
907 if (IN_SET(log_target,
908 LOG_TARGET_AUTO,
909 LOG_TARGET_JOURNAL_OR_KMSG,
910 LOG_TARGET_JOURNAL)) {
911
912 if (open_when_needed)
913 log_open_journal();
914
915 if (journal_fd >= 0) {
916 char header[LINE_MAX];
917 struct iovec iovec[17] = {};
918 size_t n = 0, i;
919 int r;
920 struct msghdr mh = {
921 .msg_iov = iovec,
922 };
923 bool fallback = false;
924
925 /* If the journal is available do structured logging.
926 * Do not report the errno if it is synthetic. */
927 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
928 iovec[n++] = IOVEC_MAKE_STRING(header);
929
930 va_start(ap, format);
931 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
932 if (r < 0)
933 fallback = true;
934 else {
935 mh.msg_iovlen = n;
936 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
937 }
938
939 va_end(ap);
940 for (i = 1; i < n; i += 2)
941 free(iovec[i].iov_base);
942
943 if (!fallback) {
944 if (open_when_needed)
945 log_close();
946
947 return -ERRNO_VALUE(error);
948 }
949 }
950 }
951
952 /* Fallback if journal logging is not available or didn't work. */
953
954 va_start(ap, format);
955 while (format) {
956 va_list aq;
957
958 errno = ERRNO_VALUE(error);
959
960 va_copy(aq, ap);
961 (void) vsnprintf(buf, sizeof buf, format, aq);
962 va_end(aq);
963
964 if (startswith(buf, "MESSAGE=")) {
965 found = true;
966 break;
967 }
968
969 VA_FORMAT_ADVANCE(format, ap);
970
971 format = va_arg(ap, char *);
972 }
973 va_end(ap);
974
975 if (!found) {
976 if (open_when_needed)
977 log_close();
978
979 return -ERRNO_VALUE(error);
980 }
981
982 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
983 }
984
985 int log_struct_iovec_internal(
986 int level,
987 int error,
988 const char *file,
989 int line,
990 const char *func,
991 const struct iovec input_iovec[],
992 size_t n_input_iovec) {
993
994 LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
995 PROTECT_ERRNO;
996 size_t i;
997 char *m;
998
999 if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
1000 log_target == LOG_TARGET_NULL)
1001 return -ERRNO_VALUE(error);
1002
1003 if ((level & LOG_FACMASK) == 0)
1004 level |= log_facility;
1005
1006 if (IN_SET(log_target, LOG_TARGET_AUTO,
1007 LOG_TARGET_JOURNAL_OR_KMSG,
1008 LOG_TARGET_JOURNAL) &&
1009 journal_fd >= 0) {
1010
1011 struct iovec iovec[1 + n_input_iovec*2];
1012 char header[LINE_MAX];
1013 struct msghdr mh = {
1014 .msg_iov = iovec,
1015 .msg_iovlen = 1 + n_input_iovec*2,
1016 };
1017
1018 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1019 iovec[0] = IOVEC_MAKE_STRING(header);
1020
1021 for (i = 0; i < n_input_iovec; i++) {
1022 iovec[1+i*2] = input_iovec[i];
1023 iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1024 }
1025
1026 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
1027 return -ERRNO_VALUE(error);
1028 }
1029
1030 for (i = 0; i < n_input_iovec; i++)
1031 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE="))
1032 break;
1033
1034 if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
1035 return -ERRNO_VALUE(error);
1036
1037 m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
1038 input_iovec[i].iov_len - STRLEN("MESSAGE="));
1039
1040 return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1041 }
1042
1043 int log_set_target_from_string(const char *e) {
1044 LogTarget t;
1045
1046 t = log_target_from_string(e);
1047 if (t < 0)
1048 return -EINVAL;
1049
1050 log_set_target(t);
1051 return 0;
1052 }
1053
1054 int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
1055 int t;
1056
1057 t = log_level_from_string(e);
1058 if (t < 0)
1059 return -EINVAL;
1060
1061 log_set_max_level_realm(realm, t);
1062 return 0;
1063 }
1064
1065 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1066
1067 /*
1068 * The systemd.log_xyz= settings are parsed by all tools, and
1069 * so is "debug".
1070 *
1071 * However, "quiet" is only parsed by PID 1, and only turns of
1072 * status output to /dev/console, but does not alter the log
1073 * level.
1074 */
1075
1076 if (streq(key, "debug") && !value)
1077 log_set_max_level(LOG_DEBUG);
1078
1079 else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1080
1081 if (proc_cmdline_value_missing(key, value))
1082 return 0;
1083
1084 if (log_set_target_from_string(value) < 0)
1085 log_warning("Failed to parse log target '%s'. Ignoring.", value);
1086
1087 } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1088
1089 if (proc_cmdline_value_missing(key, value))
1090 return 0;
1091
1092 if (log_set_max_level_from_string(value) < 0)
1093 log_warning("Failed to parse log level '%s'. Ignoring.", value);
1094
1095 } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1096
1097 if (log_show_color_from_string(value ?: "1") < 0)
1098 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1099
1100 } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1101
1102 if (log_show_location_from_string(value ?: "1") < 0)
1103 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1104 }
1105
1106 return 0;
1107 }
1108
1109 void log_parse_environment_realm(LogRealm realm) {
1110 /* Do not call from library code. */
1111
1112 const char *e;
1113
1114 if (getpid_cached() == 1 || get_ctty_devnr(0, NULL) < 0)
1115 /* Only try to read the command line in daemons. We assume that anything that has a
1116 * controlling tty is user stuff. For PID1 we do a special check in case it hasn't
1117 * closed the console yet. */
1118 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1119
1120 e = getenv("SYSTEMD_LOG_TARGET");
1121 if (e && log_set_target_from_string(e) < 0)
1122 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1123
1124 e = getenv("SYSTEMD_LOG_LEVEL");
1125 if (e && log_set_max_level_from_string_realm(realm, e) < 0)
1126 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1127
1128 e = getenv("SYSTEMD_LOG_COLOR");
1129 if (e && log_show_color_from_string(e) < 0)
1130 log_warning("Failed to parse log color '%s'. Ignoring.", e);
1131
1132 e = getenv("SYSTEMD_LOG_LOCATION");
1133 if (e && log_show_location_from_string(e) < 0)
1134 log_warning("Failed to parse log location '%s'. Ignoring.", e);
1135 }
1136
1137 LogTarget log_get_target(void) {
1138 return log_target;
1139 }
1140
1141 int log_get_max_level_realm(LogRealm realm) {
1142 return log_max_level[realm];
1143 }
1144
1145 void log_show_color(bool b) {
1146 show_color = b;
1147 }
1148
1149 bool log_get_show_color(void) {
1150 return show_color;
1151 }
1152
1153 void log_show_location(bool b) {
1154 show_location = b;
1155 }
1156
1157 bool log_get_show_location(void) {
1158 return show_location;
1159 }
1160
1161 int log_show_color_from_string(const char *e) {
1162 int t;
1163
1164 t = parse_boolean(e);
1165 if (t < 0)
1166 return t;
1167
1168 log_show_color(t);
1169 return 0;
1170 }
1171
1172 int log_show_location_from_string(const char *e) {
1173 int t;
1174
1175 t = parse_boolean(e);
1176 if (t < 0)
1177 return t;
1178
1179 log_show_location(t);
1180 return 0;
1181 }
1182
1183 bool log_on_console(void) {
1184 if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1185 LOG_TARGET_CONSOLE_PREFIXED))
1186 return true;
1187
1188 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1189 }
1190
1191 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1192 [LOG_TARGET_CONSOLE] = "console",
1193 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1194 [LOG_TARGET_KMSG] = "kmsg",
1195 [LOG_TARGET_JOURNAL] = "journal",
1196 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1197 [LOG_TARGET_SYSLOG] = "syslog",
1198 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1199 [LOG_TARGET_AUTO] = "auto",
1200 [LOG_TARGET_NULL] = "null",
1201 };
1202
1203 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1204
1205 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1206 assert(si);
1207
1208 if (pid_is_valid(si->ssi_pid)) {
1209 _cleanup_free_ char *p = NULL;
1210
1211 (void) get_process_comm(si->ssi_pid, &p);
1212
1213 log_full(level,
1214 "Received SIG%s from PID %"PRIu32" (%s).",
1215 signal_to_string(si->ssi_signo),
1216 si->ssi_pid, strna(p));
1217 } else
1218 log_full(level,
1219 "Received SIG%s.",
1220 signal_to_string(si->ssi_signo));
1221 }
1222
1223 int log_syntax_internal(
1224 const char *unit,
1225 int level,
1226 const char *config_file,
1227 unsigned config_line,
1228 int error,
1229 const char *file,
1230 int line,
1231 const char *func,
1232 const char *format, ...) {
1233
1234 PROTECT_ERRNO;
1235 char buffer[LINE_MAX];
1236 va_list ap;
1237 const char *unit_fmt = NULL;
1238
1239 if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]) ||
1240 log_target == LOG_TARGET_NULL)
1241 return -ERRNO_VALUE(error);
1242
1243 errno = ERRNO_VALUE(error);
1244
1245 va_start(ap, format);
1246 (void) vsnprintf(buffer, sizeof buffer, format, ap);
1247 va_end(ap);
1248
1249 if (unit)
1250 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1251
1252 if (config_file) {
1253 if (config_line > 0)
1254 return log_struct_internal(
1255 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1256 error,
1257 file, line, func,
1258 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1259 "CONFIG_FILE=%s", config_file,
1260 "CONFIG_LINE=%u", config_line,
1261 LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1262 unit_fmt, unit,
1263 NULL);
1264 else
1265 return log_struct_internal(
1266 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1267 error,
1268 file, line, func,
1269 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1270 "CONFIG_FILE=%s", config_file,
1271 LOG_MESSAGE("%s: %s", config_file, buffer),
1272 unit_fmt, unit,
1273 NULL);
1274 } else if (unit)
1275 return log_struct_internal(
1276 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1277 error,
1278 file, line, func,
1279 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1280 LOG_MESSAGE("%s: %s", unit, buffer),
1281 unit_fmt, unit,
1282 NULL);
1283 else
1284 return log_struct_internal(
1285 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
1286 error,
1287 file, line, func,
1288 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1289 LOG_MESSAGE("%s", buffer),
1290 NULL);
1291 }
1292
1293 int log_syntax_invalid_utf8_internal(
1294 const char *unit,
1295 int level,
1296 const char *config_file,
1297 unsigned config_line,
1298 const char *file,
1299 int line,
1300 const char *func,
1301 const char *rvalue) {
1302
1303 _cleanup_free_ char *p = NULL;
1304
1305 if (rvalue)
1306 p = utf8_escape_invalid(rvalue);
1307
1308 log_syntax_internal(unit, level, config_file, config_line, 0, file, line, func,
1309 "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1310
1311 return -EINVAL;
1312 }
1313
1314 void log_set_upgrade_syslog_to_journal(bool b) {
1315 upgrade_syslog_to_journal = b;
1316
1317 /* Make the change effective immediately */
1318 if (b) {
1319 if (log_target == LOG_TARGET_SYSLOG)
1320 log_target = LOG_TARGET_JOURNAL;
1321 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1322 log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1323 }
1324 }
1325
1326 void log_set_always_reopen_console(bool b) {
1327 always_reopen_console = b;
1328 }
1329
1330 void log_set_open_when_needed(bool b) {
1331 open_when_needed = b;
1332 }
1333
1334 void log_set_prohibit_ipc(bool b) {
1335 prohibit_ipc = b;
1336 }
1337
1338 int log_emergency_level(void) {
1339 /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1340 * then the system of the whole system is obviously affected. */
1341
1342 return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
1343 }
1344
1345 int log_dup_console(void) {
1346 int copy;
1347
1348 /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1349 * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1350
1351 if (console_fd >= 3)
1352 return 0;
1353
1354 copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1355 if (copy < 0)
1356 return -errno;
1357
1358 console_fd = copy;
1359 return 0;
1360 }
1361
1362 void log_setup_service(void) {
1363 /* Sets up logging the way it is most appropriate for running a program as a service. Note that using this
1364 * doesn't make the binary unsuitable for invocation on the command line, as log output will still go to the
1365 * terminal if invoked interactively. */
1366
1367 log_set_target(LOG_TARGET_AUTO);
1368 log_parse_environment();
1369 (void) log_open();
1370 }