]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/log.c
03ef018bd4b870268806f8e2e890180236407c00
[thirdparty/systemd.git] / src / shared / log.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <stddef.h>
30 #include <printf.h>
31
32 #include "log.h"
33 #include "util.h"
34 #include "missing.h"
35 #include "macro.h"
36 #include "socket-util.h"
37
38 #define SNDBUF_SIZE (8*1024*1024)
39
40 static LogTarget log_target = LOG_TARGET_CONSOLE;
41 static int log_max_level = LOG_INFO;
42 static int log_facility = LOG_DAEMON;
43
44 static int console_fd = STDERR_FILENO;
45 static int syslog_fd = -1;
46 static int kmsg_fd = -1;
47 static int journal_fd = -1;
48
49 static bool syslog_is_stream = false;
50
51 static bool show_color = false;
52 static bool show_location = false;
53
54 static bool upgrade_syslog_to_journal = false;
55
56 /* Akin to glibc's __abort_msg; which is private and we hence cannot
57 * use here. */
58 static char *log_abort_msg = NULL;
59
60 void log_close_console(void) {
61
62 if (console_fd < 0)
63 return;
64
65 if (getpid() == 1) {
66 if (console_fd >= 3)
67 safe_close(console_fd);
68
69 console_fd = -1;
70 }
71 }
72
73 static int log_open_console(void) {
74
75 if (console_fd >= 0)
76 return 0;
77
78 if (getpid() == 1) {
79 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
80 if (console_fd < 0)
81 return console_fd;
82 } else
83 console_fd = STDERR_FILENO;
84
85 return 0;
86 }
87
88 void log_close_kmsg(void) {
89 kmsg_fd = safe_close(kmsg_fd);
90 }
91
92 static int log_open_kmsg(void) {
93
94 if (kmsg_fd >= 0)
95 return 0;
96
97 kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
98 if (kmsg_fd < 0)
99 return -errno;
100
101 return 0;
102 }
103
104 void log_close_syslog(void) {
105 syslog_fd = safe_close(syslog_fd);
106 }
107
108 static int create_log_socket(int type) {
109 struct timeval tv;
110 int fd;
111
112 fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
113 if (fd < 0)
114 return -errno;
115
116 fd_inc_sndbuf(fd, SNDBUF_SIZE);
117
118 /* We need a blocking fd here since we'd otherwise lose
119 messages way too early. However, let's not hang forever in the
120 unlikely case of a deadlock. */
121 if (getpid() == 1)
122 timeval_store(&tv, 10 * USEC_PER_MSEC);
123 else
124 timeval_store(&tv, 10 * USEC_PER_SEC);
125 (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
126
127 return fd;
128 }
129
130 static int log_open_syslog(void) {
131
132 static const union sockaddr_union sa = {
133 .un.sun_family = AF_UNIX,
134 .un.sun_path = "/dev/log",
135 };
136
137 int r;
138
139 if (syslog_fd >= 0)
140 return 0;
141
142 syslog_fd = create_log_socket(SOCK_DGRAM);
143 if (syslog_fd < 0) {
144 r = syslog_fd;
145 goto fail;
146 }
147
148 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
149 safe_close(syslog_fd);
150
151 /* Some legacy syslog systems still use stream
152 * sockets. They really shouldn't. But what can we
153 * do... */
154 syslog_fd = create_log_socket(SOCK_STREAM);
155 if (syslog_fd < 0) {
156 r = syslog_fd;
157 goto fail;
158 }
159
160 if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
161 r = -errno;
162 goto fail;
163 }
164
165 syslog_is_stream = true;
166 } else
167 syslog_is_stream = false;
168
169 return 0;
170
171 fail:
172 log_close_syslog();
173 return r;
174 }
175
176 void log_close_journal(void) {
177 journal_fd = safe_close(journal_fd);
178 }
179
180 static int log_open_journal(void) {
181
182 static const union sockaddr_union sa = {
183 .un.sun_family = AF_UNIX,
184 .un.sun_path = "/run/systemd/journal/socket",
185 };
186
187 int r;
188
189 if (journal_fd >= 0)
190 return 0;
191
192 journal_fd = create_log_socket(SOCK_DGRAM);
193 if (journal_fd < 0) {
194 r = journal_fd;
195 goto fail;
196 }
197
198 if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
199 r = -errno;
200 goto fail;
201 }
202
203 return 0;
204
205 fail:
206 log_close_journal();
207 return r;
208 }
209
210 int log_open(void) {
211 int r;
212
213 /* If we don't use the console we close it here, to not get
214 * killed by SAK. If we don't use syslog we close it here so
215 * that we are not confused by somebody deleting the socket in
216 * the fs. If we don't use /dev/kmsg we still keep it open,
217 * because there is no reason to close it. */
218
219 if (log_target == LOG_TARGET_NULL) {
220 log_close_journal();
221 log_close_syslog();
222 log_close_console();
223 return 0;
224 }
225
226 if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
227 getpid() == 1 ||
228 isatty(STDERR_FILENO) <= 0) {
229
230 if (log_target == LOG_TARGET_AUTO ||
231 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
232 log_target == LOG_TARGET_JOURNAL) {
233 r = log_open_journal();
234 if (r >= 0) {
235 log_close_syslog();
236 log_close_console();
237 return r;
238 }
239 }
240
241 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
242 log_target == LOG_TARGET_SYSLOG) {
243 r = log_open_syslog();
244 if (r >= 0) {
245 log_close_journal();
246 log_close_console();
247 return r;
248 }
249 }
250
251 if (log_target == LOG_TARGET_AUTO ||
252 log_target == LOG_TARGET_SAFE ||
253 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
254 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
255 log_target == LOG_TARGET_KMSG) {
256 r = log_open_kmsg();
257 if (r >= 0) {
258 log_close_journal();
259 log_close_syslog();
260 log_close_console();
261 return r;
262 }
263 }
264 }
265
266 log_close_journal();
267 log_close_syslog();
268
269 return log_open_console();
270 }
271
272 void log_set_target(LogTarget target) {
273 assert(target >= 0);
274 assert(target < _LOG_TARGET_MAX);
275
276 if (upgrade_syslog_to_journal) {
277 if (target == LOG_TARGET_SYSLOG)
278 target = LOG_TARGET_JOURNAL;
279 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
280 target = LOG_TARGET_JOURNAL_OR_KMSG;
281 }
282
283 log_target = target;
284 }
285
286 void log_close(void) {
287 log_close_journal();
288 log_close_syslog();
289 log_close_kmsg();
290 log_close_console();
291 }
292
293 void log_forget_fds(void) {
294 console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
295 }
296
297 void log_set_max_level(int level) {
298 assert((level & LOG_PRIMASK) == level);
299
300 log_max_level = level;
301 }
302
303 void log_set_facility(int facility) {
304 log_facility = facility;
305 }
306
307 static int write_to_console(
308 int level,
309 int error,
310 const char *file,
311 int line,
312 const char *func,
313 const char *object_field,
314 const char *object,
315 const char *buffer) {
316
317 char location[64], prefix[1 + DECIMAL_STR_MAX(int) + 2];
318 struct iovec iovec[6] = {};
319 unsigned n = 0;
320 bool highlight;
321
322 if (console_fd < 0)
323 return 0;
324
325 if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
326 sprintf(prefix, "<%i>", level);
327 IOVEC_SET_STRING(iovec[n++], prefix);
328 }
329
330 highlight = LOG_PRI(level) <= LOG_ERR && show_color;
331
332 if (show_location) {
333 snprintf(location, sizeof(location), "(%s:%i) ", file, line);
334 IOVEC_SET_STRING(iovec[n++], location);
335 }
336
337 if (highlight)
338 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
339 IOVEC_SET_STRING(iovec[n++], buffer);
340 if (highlight)
341 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
342 IOVEC_SET_STRING(iovec[n++], "\n");
343
344 if (writev(console_fd, iovec, n) < 0) {
345
346 if (errno == EIO && getpid() == 1) {
347
348 /* If somebody tried to kick us from our
349 * console tty (via vhangup() or suchlike),
350 * try to reconnect */
351
352 log_close_console();
353 log_open_console();
354
355 if (console_fd < 0)
356 return 0;
357
358 if (writev(console_fd, iovec, n) < 0)
359 return -errno;
360 } else
361 return -errno;
362 }
363
364 return 1;
365 }
366
367 static int write_to_syslog(
368 int level,
369 int error,
370 const char *file,
371 int line,
372 const char *func,
373 const char *object_field,
374 const char *object,
375 const char *buffer) {
376
377 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
378 header_time[64],
379 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
380 struct iovec iovec[5] = {};
381 struct msghdr msghdr = {
382 .msg_iov = iovec,
383 .msg_iovlen = ELEMENTSOF(iovec),
384 };
385 time_t t;
386 struct tm *tm;
387
388 if (syslog_fd < 0)
389 return 0;
390
391 xsprintf(header_priority, "<%i>", level);
392
393 t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
394 tm = localtime(&t);
395 if (!tm)
396 return -EINVAL;
397
398 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
399 return -EINVAL;
400
401 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
402
403 IOVEC_SET_STRING(iovec[0], header_priority);
404 IOVEC_SET_STRING(iovec[1], header_time);
405 IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
406 IOVEC_SET_STRING(iovec[3], header_pid);
407 IOVEC_SET_STRING(iovec[4], buffer);
408
409 /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
410 if (syslog_is_stream)
411 iovec[4].iov_len++;
412
413 for (;;) {
414 ssize_t n;
415
416 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
417 if (n < 0)
418 return -errno;
419
420 if (!syslog_is_stream ||
421 (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
422 break;
423
424 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
425 }
426
427 return 1;
428 }
429
430 static int write_to_kmsg(
431 int level,
432 int error,
433 const char*file,
434 int line,
435 const char *func,
436 const char *object_field,
437 const char *object,
438 const char *buffer) {
439
440 char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
441 header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
442 struct iovec iovec[5] = {};
443
444 if (kmsg_fd < 0)
445 return 0;
446
447 xsprintf(header_priority, "<%i>", level);
448 xsprintf(header_pid, "["PID_FMT"]: ", getpid());
449
450 IOVEC_SET_STRING(iovec[0], header_priority);
451 IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
452 IOVEC_SET_STRING(iovec[2], header_pid);
453 IOVEC_SET_STRING(iovec[3], buffer);
454 IOVEC_SET_STRING(iovec[4], "\n");
455
456 if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
457 return -errno;
458
459 return 1;
460 }
461
462 static int log_do_header(
463 char *header,
464 size_t size,
465 int level,
466 int error,
467 const char *file, int line, const char *func,
468 const char *object_field, const char *object) {
469
470 snprintf(header, size,
471 "PRIORITY=%i\n"
472 "SYSLOG_FACILITY=%i\n"
473 "%s%s%s"
474 "%s%.*i%s"
475 "%s%s%s"
476 "%s%.*i%s"
477 "%s%s%s"
478 "SYSLOG_IDENTIFIER=%s\n",
479 LOG_PRI(level),
480 LOG_FAC(level),
481 isempty(file) ? "" : "CODE_FILE=",
482 isempty(file) ? "" : file,
483 isempty(file) ? "" : "\n",
484 line ? "CODE_LINE=" : "",
485 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
486 line ? "\n" : "",
487 isempty(func) ? "" : "CODE_FUNCTION=",
488 isempty(func) ? "" : func,
489 isempty(func) ? "" : "\n",
490 error ? "ERRNO=" : "",
491 error ? 1 : 0, error,
492 error ? "\n" : "",
493 isempty(object) ? "" : object_field,
494 isempty(object) ? "" : object,
495 isempty(object) ? "" : "\n",
496 program_invocation_short_name);
497
498 return 0;
499 }
500
501 static int write_to_journal(
502 int level,
503 int error,
504 const char*file,
505 int line,
506 const char *func,
507 const char *object_field,
508 const char *object,
509 const char *buffer) {
510
511 char header[LINE_MAX];
512 struct iovec iovec[4] = {};
513 struct msghdr mh = {};
514
515 if (journal_fd < 0)
516 return 0;
517
518 log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
519
520 IOVEC_SET_STRING(iovec[0], header);
521 IOVEC_SET_STRING(iovec[1], "MESSAGE=");
522 IOVEC_SET_STRING(iovec[2], buffer);
523 IOVEC_SET_STRING(iovec[3], "\n");
524
525 mh.msg_iov = iovec;
526 mh.msg_iovlen = ELEMENTSOF(iovec);
527
528 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
529 return -errno;
530
531 return 1;
532 }
533
534 static int log_dispatch(
535 int level,
536 int error,
537 const char *file,
538 int line,
539 const char *func,
540 const char *object_field,
541 const char *object,
542 char *buffer) {
543
544 assert(buffer);
545
546 if (log_target == LOG_TARGET_NULL)
547 return -error;
548
549 /* Patch in LOG_DAEMON facility if necessary */
550 if ((level & LOG_FACMASK) == 0)
551 level = log_facility | LOG_PRI(level);
552
553 if (error < 0)
554 error = -error;
555
556 do {
557 char *e;
558 int k = 0;
559
560 buffer += strspn(buffer, NEWLINE);
561
562 if (buffer[0] == 0)
563 break;
564
565 if ((e = strpbrk(buffer, NEWLINE)))
566 *(e++) = 0;
567
568 if (log_target == LOG_TARGET_AUTO ||
569 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
570 log_target == LOG_TARGET_JOURNAL) {
571
572 k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
573 if (k < 0) {
574 if (k != -EAGAIN)
575 log_close_journal();
576 log_open_kmsg();
577 }
578 }
579
580 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
581 log_target == LOG_TARGET_SYSLOG) {
582
583 k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
584 if (k < 0) {
585 if (k != -EAGAIN)
586 log_close_syslog();
587 log_open_kmsg();
588 }
589 }
590
591 if (k <= 0 &&
592 (log_target == LOG_TARGET_AUTO ||
593 log_target == LOG_TARGET_SAFE ||
594 log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
595 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
596 log_target == LOG_TARGET_KMSG)) {
597
598 k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
599 if (k < 0) {
600 log_close_kmsg();
601 log_open_console();
602 }
603 }
604
605 if (k <= 0)
606 (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
607
608 buffer = e;
609 } while (buffer);
610
611 return -error;
612 }
613
614 int log_dump_internal(
615 int level,
616 int error,
617 const char *file,
618 int line,
619 const char *func,
620 char *buffer) {
621
622 PROTECT_ERRNO;
623
624 /* This modifies the buffer... */
625
626 if (error < 0)
627 error = -error;
628
629 if (_likely_(LOG_PRI(level) > log_max_level))
630 return -error;
631
632 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
633 }
634
635 int log_internalv(
636 int level,
637 int error,
638 const char*file,
639 int line,
640 const char *func,
641 const char *format,
642 va_list ap) {
643
644 PROTECT_ERRNO;
645 char buffer[LINE_MAX];
646
647 if (error < 0)
648 error = -error;
649
650 if (_likely_(LOG_PRI(level) > log_max_level))
651 return -error;
652
653 /* Make sure that %m maps to the specified error */
654 if (error != 0)
655 errno = error;
656
657 vsnprintf(buffer, sizeof(buffer), format, ap);
658
659 return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
660 }
661
662 int log_internal(
663 int level,
664 int error,
665 const char*file,
666 int line,
667 const char *func,
668 const char *format, ...) {
669
670 va_list ap;
671 int r;
672
673 va_start(ap, format);
674 r = log_internalv(level, error, file, line, func, format, ap);
675 va_end(ap);
676
677 return r;
678 }
679
680 int log_object_internalv(
681 int level,
682 int error,
683 const char*file,
684 int line,
685 const char *func,
686 const char *object_field,
687 const char *object,
688 const char *format,
689 va_list ap) {
690
691 PROTECT_ERRNO;
692 char buffer[LINE_MAX];
693
694 if (error < 0)
695 error = -error;
696
697 if (_likely_(LOG_PRI(level) > log_max_level))
698 return -error;
699
700 /* Make sure that %m maps to the specified error */
701 if (error != 0)
702 errno = error;
703
704 vsnprintf(buffer, sizeof(buffer), format, ap);
705
706 return log_dispatch(level, error, file, line, func, object_field, object, buffer);
707 }
708
709 int log_object_internal(
710 int level,
711 int error,
712 const char*file,
713 int line,
714 const char *func,
715 const char *object_field,
716 const char *object,
717 const char *format, ...) {
718
719 va_list ap;
720 int r;
721
722 va_start(ap, format);
723 r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
724 va_end(ap);
725
726 return r;
727 }
728
729 static void log_assert(
730 int level,
731 const char *text,
732 const char *file,
733 int line,
734 const char *func,
735 const char *format) {
736
737 static char buffer[LINE_MAX];
738
739 if (_likely_(LOG_PRI(level) > log_max_level))
740 return;
741
742 DISABLE_WARNING_FORMAT_NONLITERAL;
743 snprintf(buffer, sizeof(buffer), format, text, file, line, func);
744 REENABLE_WARNING;
745
746 log_abort_msg = buffer;
747
748 log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
749 }
750
751 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
752 log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
753 abort();
754 }
755
756 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
757 log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
758 abort();
759 }
760
761 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
762 PROTECT_ERRNO;
763 log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
764 }
765
766 int log_oom_internal(const char *file, int line, const char *func) {
767 log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
768 return -ENOMEM;
769 }
770
771 int log_struct_internal(
772 int level,
773 int error,
774 const char *file,
775 int line,
776 const char *func,
777 const char *format, ...) {
778
779 char buf[LINE_MAX];
780 bool found = false;
781 PROTECT_ERRNO;
782 va_list ap;
783
784 if (error < 0)
785 error = -error;
786
787 if (_likely_(LOG_PRI(level) > log_max_level))
788 return -error;
789
790 if (log_target == LOG_TARGET_NULL)
791 return -error;
792
793 if ((level & LOG_FACMASK) == 0)
794 level = log_facility | LOG_PRI(level);
795
796 if ((log_target == LOG_TARGET_AUTO ||
797 log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
798 log_target == LOG_TARGET_JOURNAL) &&
799 journal_fd >= 0) {
800 char header[LINE_MAX];
801 struct iovec iovec[17] = {};
802 unsigned n = 0, i;
803 struct msghdr mh = {
804 .msg_iov = iovec,
805 };
806 static const char nl = '\n';
807 bool fallback = false;
808
809 /* If the journal is available do structured logging */
810 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
811 IOVEC_SET_STRING(iovec[n++], header);
812
813 va_start(ap, format);
814 while (format && n + 1 < ELEMENTSOF(iovec)) {
815 va_list aq;
816 char *m;
817
818 /* We need to copy the va_list structure,
819 * since vasprintf() leaves it afterwards at
820 * an undefined location */
821
822 if (error != 0)
823 errno = error;
824
825 va_copy(aq, ap);
826 if (vasprintf(&m, format, aq) < 0) {
827 va_end(aq);
828 fallback = true;
829 goto finish;
830 }
831 va_end(aq);
832
833 /* Now, jump enough ahead, so that we point to
834 * the next format string */
835 VA_FORMAT_ADVANCE(format, ap);
836
837 IOVEC_SET_STRING(iovec[n++], m);
838
839 iovec[n].iov_base = (char*) &nl;
840 iovec[n].iov_len = 1;
841 n++;
842
843 format = va_arg(ap, char *);
844 }
845
846 mh.msg_iovlen = n;
847
848 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
849
850 finish:
851 va_end(ap);
852 for (i = 1; i < n; i += 2)
853 free(iovec[i].iov_base);
854
855 if (!fallback)
856 return -error;
857 }
858
859 /* Fallback if journal logging is not available or didn't work. */
860
861 va_start(ap, format);
862 while (format) {
863 va_list aq;
864
865 if (error != 0)
866 errno = error;
867
868 va_copy(aq, ap);
869 vsnprintf(buf, sizeof(buf), format, aq);
870 va_end(aq);
871
872 if (startswith(buf, "MESSAGE=")) {
873 found = true;
874 break;
875 }
876
877 VA_FORMAT_ADVANCE(format, ap);
878
879 format = va_arg(ap, char *);
880 }
881 va_end(ap);
882
883 if (!found)
884 return -error;
885
886 return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
887 }
888
889 int log_set_target_from_string(const char *e) {
890 LogTarget t;
891
892 t = log_target_from_string(e);
893 if (t < 0)
894 return -EINVAL;
895
896 log_set_target(t);
897 return 0;
898 }
899
900 int log_set_max_level_from_string(const char *e) {
901 int t;
902
903 t = log_level_from_string(e);
904 if (t < 0)
905 return t;
906
907 log_set_max_level(t);
908 return 0;
909 }
910
911 static int parse_proc_cmdline_item(const char *key, const char *value) {
912
913 /*
914 * The systemd.log_xyz= settings are parsed by all tools, and
915 * so is "debug".
916 *
917 * However, "quiet" is only parsed by PID 1, and only turns of
918 * status output to /dev/console, but does not alter the log
919 * level.
920 */
921
922 if (streq(key, "debug") && !value)
923 log_set_max_level(LOG_DEBUG);
924
925 else if (streq(key, "systemd.log_target") && value) {
926
927 if (log_set_target_from_string(value) < 0)
928 log_warning("Failed to parse log target '%s'. Ignoring.", value);
929
930 } else if (streq(key, "systemd.log_level") && value) {
931
932 if (log_set_max_level_from_string(value) < 0)
933 log_warning("Failed to parse log level '%s'. Ignoring.", value);
934
935 } else if (streq(key, "systemd.log_color") && value) {
936
937 if (log_show_color_from_string(value) < 0)
938 log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
939
940 } else if (streq(key, "systemd.log_location") && value) {
941
942 if (log_show_location_from_string(value) < 0)
943 log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
944 }
945
946 return 0;
947 }
948
949 void log_parse_environment(void) {
950 const char *e;
951
952 (void) parse_proc_cmdline(parse_proc_cmdline_item);
953
954 e = secure_getenv("SYSTEMD_LOG_TARGET");
955 if (e && log_set_target_from_string(e) < 0)
956 log_warning("Failed to parse log target '%s'. Ignoring.", e);
957
958 e = secure_getenv("SYSTEMD_LOG_LEVEL");
959 if (e && log_set_max_level_from_string(e) < 0)
960 log_warning("Failed to parse log level '%s'. Ignoring.", e);
961
962 e = secure_getenv("SYSTEMD_LOG_COLOR");
963 if (e && log_show_color_from_string(e) < 0)
964 log_warning("Failed to parse bool '%s'. Ignoring.", e);
965
966 e = secure_getenv("SYSTEMD_LOG_LOCATION");
967 if (e && log_show_location_from_string(e) < 0)
968 log_warning("Failed to parse bool '%s'. Ignoring.", e);
969 }
970
971 LogTarget log_get_target(void) {
972 return log_target;
973 }
974
975 int log_get_max_level(void) {
976 return log_max_level;
977 }
978
979 void log_show_color(bool b) {
980 show_color = b;
981 }
982
983 bool log_get_show_color(void) {
984 return show_color;
985 }
986
987 void log_show_location(bool b) {
988 show_location = b;
989 }
990
991 bool log_get_show_location(void) {
992 return show_location;
993 }
994
995 int log_show_color_from_string(const char *e) {
996 int t;
997
998 t = parse_boolean(e);
999 if (t < 0)
1000 return t;
1001
1002 log_show_color(t);
1003 return 0;
1004 }
1005
1006 int log_show_location_from_string(const char *e) {
1007 int t;
1008
1009 t = parse_boolean(e);
1010 if (t < 0)
1011 return t;
1012
1013 log_show_location(t);
1014 return 0;
1015 }
1016
1017 bool log_on_console(void) {
1018 if (log_target == LOG_TARGET_CONSOLE ||
1019 log_target == LOG_TARGET_CONSOLE_PREFIXED)
1020 return true;
1021
1022 return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1023 }
1024
1025 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1026 [LOG_TARGET_CONSOLE] = "console",
1027 [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1028 [LOG_TARGET_KMSG] = "kmsg",
1029 [LOG_TARGET_JOURNAL] = "journal",
1030 [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1031 [LOG_TARGET_SYSLOG] = "syslog",
1032 [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1033 [LOG_TARGET_AUTO] = "auto",
1034 [LOG_TARGET_SAFE] = "safe",
1035 [LOG_TARGET_NULL] = "null"
1036 };
1037
1038 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1039
1040 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1041 if (si->ssi_pid > 0) {
1042 _cleanup_free_ char *p = NULL;
1043
1044 get_process_comm(si->ssi_pid, &p);
1045
1046 log_full(level,
1047 "Received SIG%s from PID %"PRIu32" (%s).",
1048 signal_to_string(si->ssi_signo),
1049 si->ssi_pid, strna(p));
1050 } else
1051 log_full(level,
1052 "Received SIG%s.",
1053 signal_to_string(si->ssi_signo));
1054
1055 }
1056
1057 void log_set_upgrade_syslog_to_journal(bool b) {
1058 upgrade_syslog_to_journal = b;
1059 }