diff --git a/src/basic/log.c b/src/basic/log.c index 59bc16f64e..4f0fe54579 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -74,6 +74,7 @@ static bool show_location = false; static bool upgrade_syslog_to_journal = false; static bool always_reopen_console = false; +static bool open_when_needed = false; /* Akin to glibc's __abort_msg; which is private and we hence cannot * use here. */ @@ -585,6 +586,9 @@ int log_dispatch_internal( if ((level & LOG_FACMASK) == 0) level = log_facility | LOG_PRI(level); + if (open_when_needed) + log_open(); + do { char *e; int k = 0; @@ -640,6 +644,9 @@ int log_dispatch_internal( buffer = e; } while (buffer); + if (open_when_needed) + log_close(); + return -error; } @@ -910,38 +917,48 @@ int log_struct_internal( if ((level & LOG_FACMASK) == 0) level = log_facility | LOG_PRI(level); - if (IN_SET(log_target, LOG_TARGET_AUTO, - LOG_TARGET_JOURNAL_OR_KMSG, - LOG_TARGET_JOURNAL) && - journal_fd >= 0) { - char header[LINE_MAX]; - struct iovec iovec[17] = {}; - unsigned n = 0, i; - int r; - struct msghdr mh = { - .msg_iov = iovec, - }; - bool fallback = false; + if (IN_SET(log_target, + LOG_TARGET_AUTO, + LOG_TARGET_JOURNAL_OR_KMSG, + LOG_TARGET_JOURNAL)) { - /* If the journal is available do structured logging */ - log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL); - iovec[n++] = IOVEC_MAKE_STRING(header); + if (open_when_needed) + log_open_journal(); - va_start(ap, format); - r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap); - if (r < 0) - fallback = true; - else { - mh.msg_iovlen = n; - (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL); + if (journal_fd >= 0) { + char header[LINE_MAX]; + struct iovec iovec[17] = {}; + unsigned n = 0, i; + int r; + struct msghdr mh = { + .msg_iov = iovec, + }; + bool fallback = false; + + /* If the journal is available do structured logging */ + log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL); + iovec[n++] = IOVEC_MAKE_STRING(header); + + va_start(ap, format); + r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap); + if (r < 0) + fallback = true; + else { + mh.msg_iovlen = n; + (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL); + } + + va_end(ap); + for (i = 1; i < n; i += 2) + free(iovec[i].iov_base); + + if (!fallback) { + if (open_when_needed) + log_close(); + + return -error; + } } - - va_end(ap); - for (i = 1; i < n; i += 2) - free(iovec[i].iov_base); - - if (!fallback) - return -error; } /* Fallback if journal logging is not available or didn't work. */ @@ -968,8 +985,12 @@ int log_struct_internal( } va_end(ap); - if (!found) + if (!found) { + if (open_when_needed) + log_close(); + return -error; + } return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8); } @@ -1220,10 +1241,6 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) { } -void log_set_upgrade_syslog_to_journal(bool b) { - upgrade_syslog_to_journal = b; -} - int log_syntax_internal( const char *unit, int level, @@ -1271,6 +1288,14 @@ int log_syntax_internal( NULL); } +void log_set_upgrade_syslog_to_journal(bool b) { + upgrade_syslog_to_journal = b; +} + void log_set_always_reopen_console(bool b) { always_reopen_console = b; } + +void log_set_open_when_needed(bool b) { + open_when_needed = b; +} diff --git a/src/basic/log.h b/src/basic/log.h index e3fd3203d0..10a6032788 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -303,6 +303,7 @@ void log_received_signal(int level, const struct signalfd_siginfo *si); void log_set_upgrade_syslog_to_journal(bool b); void log_set_always_reopen_console(bool b); +void log_set_open_when_needed(bool b); int log_syntax_internal( const char *unit,