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