chiark / gitweb /
virt: when detecting containers and /run/systemd/container cannot be read, check...
[elogind.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];
318         struct iovec iovec[5] = {};
319         unsigned n = 0;
320         bool highlight;
321
322         if (console_fd < 0)
323                 return 0;
324
325         highlight = LOG_PRI(level) <= LOG_ERR && show_color;
326
327         if (show_location) {
328                 snprintf(location, sizeof(location), "(%s:%u) ", file, line);
329                 char_array_0(location);
330                 IOVEC_SET_STRING(iovec[n++], location);
331         }
332
333         if (highlight)
334                 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
335         IOVEC_SET_STRING(iovec[n++], buffer);
336         if (highlight)
337                 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
338         IOVEC_SET_STRING(iovec[n++], "\n");
339
340         if (writev(console_fd, iovec, n) < 0) {
341
342                 if (errno == EIO && getpid() == 1) {
343
344                         /* If somebody tried to kick us from our
345                          * console tty (via vhangup() or suchlike),
346                          * try to reconnect */
347
348                         log_close_console();
349                         log_open_console();
350
351                         if (console_fd < 0)
352                                 return 0;
353
354                         if (writev(console_fd, iovec, n) < 0)
355                                 return -errno;
356                 } else
357                         return -errno;
358         }
359
360         return 1;
361 }
362
363 static int write_to_syslog(
364                 int level,
365                 int error,
366                 const char *file,
367                 int line,
368                 const char *func,
369                 const char *object_field,
370                 const char *object,
371                 const char *buffer) {
372
373         char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_time[64], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
374         struct iovec iovec[5] = {};
375         struct msghdr msghdr = {
376                 .msg_iov = iovec,
377                 .msg_iovlen = ELEMENTSOF(iovec),
378         };
379         time_t t;
380         struct tm *tm;
381
382         if (syslog_fd < 0)
383                 return 0;
384
385         snprintf(header_priority, sizeof(header_priority), "<%i>", level);
386         char_array_0(header_priority);
387
388         t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
389         tm = localtime(&t);
390         if (!tm)
391                 return -EINVAL;
392
393         if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
394                 return -EINVAL;
395
396         snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
397         char_array_0(header_pid);
398
399         IOVEC_SET_STRING(iovec[0], header_priority);
400         IOVEC_SET_STRING(iovec[1], header_time);
401         IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
402         IOVEC_SET_STRING(iovec[3], header_pid);
403         IOVEC_SET_STRING(iovec[4], buffer);
404
405         /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
406         if (syslog_is_stream)
407                 iovec[4].iov_len++;
408
409         for (;;) {
410                 ssize_t n;
411
412                 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
413                 if (n < 0)
414                         return -errno;
415
416                 if (!syslog_is_stream ||
417                     (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
418                         break;
419
420                 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
421         }
422
423         return 1;
424 }
425
426 static int write_to_kmsg(
427                 int level,
428                 int error,
429                 const char*file,
430                 int line,
431                 const char *func,
432                 const char *object_field,
433                 const char *object,
434                 const char *buffer) {
435
436         char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4];
437         struct iovec iovec[5] = {};
438
439         if (kmsg_fd < 0)
440                 return 0;
441
442         snprintf(header_priority, sizeof(header_priority), "<%i>", level);
443         char_array_0(header_priority);
444
445         snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
446         char_array_0(header_pid);
447
448         IOVEC_SET_STRING(iovec[0], header_priority);
449         IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
450         IOVEC_SET_STRING(iovec[2], header_pid);
451         IOVEC_SET_STRING(iovec[3], buffer);
452         IOVEC_SET_STRING(iovec[4], "\n");
453
454         if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
455                 return -errno;
456
457         return 1;
458 }
459
460 static int log_do_header(
461                 char *header,
462                 size_t size,
463                 int level,
464                 int error,
465                 const char *file, int line, const char *func,
466                 const char *object_field, const char *object) {
467
468         snprintf(header, size,
469                  "PRIORITY=%i\n"
470                  "SYSLOG_FACILITY=%i\n"
471                  "%s%s%s"
472                  "%s%.*i%s"
473                  "%s%s%s"
474                  "%s%.*i%s"
475                  "%s%s%s"
476                  "SYSLOG_IDENTIFIER=%s\n",
477                  LOG_PRI(level),
478                  LOG_FAC(level),
479                  isempty(file) ? "" : "CODE_FILE=",
480                  isempty(file) ? "" : file,
481                  isempty(file) ? "" : "\n",
482                  line ? "CODE_LINE=" : "",
483                  line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
484                  line ? "\n" : "",
485                  isempty(func) ? "" : "CODE_FUNCTION=",
486                  isempty(func) ? "" : func,
487                  isempty(func) ? "" : "\n",
488                  error ? "ERRNO=" : "",
489                  error ? 1 : 0, error,
490                  error ? "\n" : "",
491                  isempty(object) ? "" : object_field,
492                  isempty(object) ? "" : object,
493                  isempty(object) ? "" : "\n",
494                  program_invocation_short_name);
495         header[size - 1] = '\0';
496
497         return 0;
498 }
499
500 static int write_to_journal(
501                 int level,
502                 int error,
503                 const char*file,
504                 int line,
505                 const char *func,
506                 const char *object_field,
507                 const char *object,
508                 const char *buffer) {
509
510         char header[LINE_MAX];
511         struct iovec iovec[4] = {};
512         struct msghdr mh = {};
513
514         if (journal_fd < 0)
515                 return 0;
516
517         log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
518
519         IOVEC_SET_STRING(iovec[0], header);
520         IOVEC_SET_STRING(iovec[1], "MESSAGE=");
521         IOVEC_SET_STRING(iovec[2], buffer);
522         IOVEC_SET_STRING(iovec[3], "\n");
523
524         mh.msg_iov = iovec;
525         mh.msg_iovlen = ELEMENTSOF(iovec);
526
527         if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
528                 return -errno;
529
530         return 1;
531 }
532
533 static int log_dispatch(
534                 int level,
535                 int error,
536                 const char *file,
537                 int line,
538                 const char *func,
539                 const char *object_field,
540                 const char *object,
541                 char *buffer) {
542
543         assert(buffer);
544
545         if (log_target == LOG_TARGET_NULL)
546                 return -error;
547
548         /* Patch in LOG_DAEMON facility if necessary */
549         if ((level & LOG_FACMASK) == 0)
550                 level = log_facility | LOG_PRI(level);
551
552         if (error < 0)
553                 error = -error;
554
555         do {
556                 char *e;
557                 int k = 0;
558
559                 buffer += strspn(buffer, NEWLINE);
560
561                 if (buffer[0] == 0)
562                         break;
563
564                 if ((e = strpbrk(buffer, NEWLINE)))
565                         *(e++) = 0;
566
567                 if (log_target == LOG_TARGET_AUTO ||
568                     log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
569                     log_target == LOG_TARGET_JOURNAL) {
570
571                         k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
572                         if (k < 0) {
573                                 if (k != -EAGAIN)
574                                         log_close_journal();
575                                 log_open_kmsg();
576                         }
577                 }
578
579                 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
580                     log_target == LOG_TARGET_SYSLOG) {
581
582                         k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
583                         if (k < 0) {
584                                 if (k != -EAGAIN)
585                                         log_close_syslog();
586                                 log_open_kmsg();
587                         }
588                 }
589
590                 if (k <= 0 &&
591                     (log_target == LOG_TARGET_AUTO ||
592                      log_target == LOG_TARGET_SAFE ||
593                      log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
594                      log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
595                      log_target == LOG_TARGET_KMSG)) {
596
597                         k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
598                         if (k < 0) {
599                                 log_close_kmsg();
600                                 log_open_console();
601                         }
602                 }
603
604                 if (k <= 0)
605                         (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
606
607                 buffer = e;
608         } while (buffer);
609
610         return -error;
611 }
612
613 int log_dump_internal(
614         int level,
615         int error,
616         const char *file,
617         int line,
618         const char *func,
619         char *buffer) {
620
621         PROTECT_ERRNO;
622
623         /* This modifies the buffer... */
624
625         if (error < 0)
626                 error = -error;
627
628         if (_likely_(LOG_PRI(level) > log_max_level))
629                 return -error;
630
631         return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
632 }
633
634 int log_internalv(
635                 int level,
636                 int error,
637                 const char*file,
638                 int line,
639                 const char *func,
640                 const char *format,
641                 va_list ap) {
642
643         PROTECT_ERRNO;
644         char buffer[LINE_MAX];
645
646         if (error < 0)
647                 error = -error;
648
649         if (_likely_(LOG_PRI(level) > log_max_level))
650                 return -error;
651
652         /* Make sure that %m maps to the specified error */
653         if (error != 0)
654                 errno = error;
655
656         vsnprintf(buffer, sizeof(buffer), format, ap);
657         char_array_0(buffer);
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         char_array_0(buffer);
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         char_array_0(buffer);
748         log_abort_msg = buffer;
749
750         log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
751 }
752
753 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
754         log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
755         abort();
756 }
757
758 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
759         log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
760         abort();
761 }
762
763 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
764         PROTECT_ERRNO;
765         log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
766 }
767
768 int log_oom_internal(const char *file, int line, const char *func) {
769         log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
770         return -ENOMEM;
771 }
772
773 int log_struct_internal(
774                 int level,
775                 int error,
776                 const char *file,
777                 int line,
778                 const char *func,
779                 const char *format, ...) {
780
781         char buf[LINE_MAX];
782         bool found = false;
783         PROTECT_ERRNO;
784         va_list ap;
785
786         if (error < 0)
787                 error = -error;
788
789         if (_likely_(LOG_PRI(level) > log_max_level))
790                 return -error;
791
792         if (log_target == LOG_TARGET_NULL)
793                 return -error;
794
795         if ((level & LOG_FACMASK) == 0)
796                 level = log_facility | LOG_PRI(level);
797
798         if ((log_target == LOG_TARGET_AUTO ||
799              log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
800              log_target == LOG_TARGET_JOURNAL) &&
801             journal_fd >= 0) {
802                 char header[LINE_MAX];
803                 struct iovec iovec[17] = {};
804                 unsigned n = 0, i;
805                 struct msghdr mh = {
806                         .msg_iov = iovec,
807                 };
808                 static const char nl = '\n';
809                 bool fallback = false;
810
811                 /* If the journal is available do structured logging */
812                 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
813                 IOVEC_SET_STRING(iovec[n++], header);
814
815                 va_start(ap, format);
816                 while (format && n + 1 < ELEMENTSOF(iovec)) {
817                         va_list aq;
818                         char *m;
819
820                         /* We need to copy the va_list structure,
821                          * since vasprintf() leaves it afterwards at
822                          * an undefined location */
823
824                         if (error != 0)
825                                 errno = error;
826
827                         va_copy(aq, ap);
828                         if (vasprintf(&m, format, aq) < 0) {
829                                 va_end(aq);
830                                 fallback = true;
831                                 goto finish;
832                         }
833                         va_end(aq);
834
835                         /* Now, jump enough ahead, so that we point to
836                          * the next format string */
837                         VA_FORMAT_ADVANCE(format, ap);
838
839                         IOVEC_SET_STRING(iovec[n++], m);
840
841                         iovec[n].iov_base = (char*) &nl;
842                         iovec[n].iov_len = 1;
843                         n++;
844
845                         format = va_arg(ap, char *);
846                 }
847
848                 mh.msg_iovlen = n;
849
850                 (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
851
852         finish:
853                 va_end(ap);
854                 for (i = 1; i < n; i += 2)
855                         free(iovec[i].iov_base);
856
857                 if (!fallback)
858                         return -error;
859         }
860
861         /* Fallback if journal logging is not available or didn't work. */
862
863         va_start(ap, format);
864         while (format) {
865                 va_list aq;
866
867                 if (error != 0)
868                         errno = error;
869
870                 va_copy(aq, ap);
871                 vsnprintf(buf, sizeof(buf), format, aq);
872                 va_end(aq);
873                 char_array_0(buf);
874
875                 if (startswith(buf, "MESSAGE=")) {
876                         found = true;
877                         break;
878                 }
879
880                 VA_FORMAT_ADVANCE(format, ap);
881
882                 format = va_arg(ap, char *);
883         }
884         va_end(ap);
885
886         if (!found)
887                 return -error;
888
889         return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
890 }
891
892 int log_set_target_from_string(const char *e) {
893         LogTarget t;
894
895         t = log_target_from_string(e);
896         if (t < 0)
897                 return -EINVAL;
898
899         log_set_target(t);
900         return 0;
901 }
902
903 int log_set_max_level_from_string(const char *e) {
904         int t;
905
906         t = log_level_from_string(e);
907         if (t < 0)
908                 return t;
909
910         log_set_max_level(t);
911         return 0;
912 }
913
914 static int parse_proc_cmdline_item(const char *key, const char *value) {
915
916         /*
917          * The systemd.log_xyz= settings are parsed by all tools, and
918          * so is "debug".
919          *
920          * However, "quiet" is only parsed by PID 1!
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         (void) parse_proc_cmdline(parse_proc_cmdline_item);
954
955         e = secure_getenv("SYSTEMD_LOG_TARGET");
956         if (e && log_set_target_from_string(e) < 0)
957                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
958
959         e = secure_getenv("SYSTEMD_LOG_LEVEL");
960         if (e && log_set_max_level_from_string(e) < 0)
961                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
962
963         e = secure_getenv("SYSTEMD_LOG_COLOR");
964         if (e && log_show_color_from_string(e) < 0)
965                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
966
967         e = secure_getenv("SYSTEMD_LOG_LOCATION");
968         if (e && log_show_location_from_string(e) < 0)
969                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
970 }
971
972 LogTarget log_get_target(void) {
973         return log_target;
974 }
975
976 int log_get_max_level(void) {
977         return log_max_level;
978 }
979
980 void log_show_color(bool b) {
981         show_color = b;
982 }
983
984 bool log_get_show_color(void) {
985         return show_color;
986 }
987
988 void log_show_location(bool b) {
989         show_location = b;
990 }
991
992 bool log_get_show_location(void) {
993         return show_location;
994 }
995
996 int log_show_color_from_string(const char *e) {
997         int t;
998
999         t = parse_boolean(e);
1000         if (t < 0)
1001                 return t;
1002
1003         log_show_color(t);
1004         return 0;
1005 }
1006
1007 int log_show_location_from_string(const char *e) {
1008         int t;
1009
1010         t = parse_boolean(e);
1011         if (t < 0)
1012                 return t;
1013
1014         log_show_location(t);
1015         return 0;
1016 }
1017
1018 bool log_on_console(void) {
1019         if (log_target == LOG_TARGET_CONSOLE)
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_KMSG] = "kmsg",
1028         [LOG_TARGET_JOURNAL] = "journal",
1029         [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1030         [LOG_TARGET_SYSLOG] = "syslog",
1031         [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1032         [LOG_TARGET_AUTO] = "auto",
1033         [LOG_TARGET_SAFE] = "safe",
1034         [LOG_TARGET_NULL] = "null"
1035 };
1036
1037 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1038
1039 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1040         if (si->ssi_pid > 0) {
1041                 _cleanup_free_ char *p = NULL;
1042
1043                 get_process_comm(si->ssi_pid, &p);
1044
1045                 log_full(level,
1046                          "Received SIG%s from PID "PID_FMT" (%s).",
1047                          signal_to_string(si->ssi_signo),
1048                          si->ssi_pid, strna(p));
1049         } else
1050                 log_full(level,
1051                          "Received SIG%s.",
1052                          signal_to_string(si->ssi_signo));
1053
1054 }
1055
1056 void log_set_upgrade_syslog_to_journal(bool b) {
1057         upgrade_syslog_to_journal = b;
1058 }