]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/log.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / log.c
index 168c6c37ceb0e432395c67e9366f6fa613340d8c..18a1ea0bdbf4ae919a8fc6f940a6ada049d646f9 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -74,6 +75,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 +587,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 +645,9 @@ int log_dispatch_internal(
                 buffer = e;
         } while (buffer);
 
+        if (open_when_needed)
+                log_close();
+
         return -error;
 }
 
@@ -834,15 +842,14 @@ void log_assert_failed_return_realm(
 }
 
 int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
-        log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
-                           ENOMEM, file, line, func, "Out of memory.");
-        return -ENOMEM;
+        return log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
+                                  ENOMEM, file, line, func, "Out of memory.");
 }
 
 int log_format_iovec(
                 struct iovec *iovec,
-                unsigned iovec_len,
-                unsigned *n,
+                size_t iovec_len,
+                size_t *n,
                 bool newline_separator,
                 int error,
                 const char *format,
@@ -911,38 +918,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 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 (IN_SET(log_target,
+                   LOG_TARGET_AUTO,
+                   LOG_TARGET_JOURNAL_OR_KMSG,
+                   LOG_TARGET_JOURNAL)) {
+
+                if (open_when_needed)
+                        log_open_journal();
+
+                if (journal_fd >= 0) {
+                        char header[LINE_MAX];
+                        struct iovec iovec[17] = {};
+                        size_t 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_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);
 
-                va_end(ap);
-                for (i = 1; i < n; i += 2)
-                        free(iovec[i].iov_base);
+                        if (!fallback) {
+                                if (open_when_needed)
+                                        log_close();
 
-                if (!fallback)
-                        return -error;
+                                return -error;
+                        }
+                }
         }
 
         /* Fallback if journal logging is not available or didn't work. */
@@ -969,8 +986,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);
 }
@@ -1221,10 +1242,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,
@@ -1272,6 +1289,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;
+}