log: add a mode where we open the log fds for every single log message
authorLennart Poettering <lennart@poettering.net>
Tue, 26 Sep 2017 15:45:09 +0000 (17:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 Sep 2017 15:46:33 +0000 (17:46 +0200)
This we can then make use in execute.c to make error logging a bit less
special when preparing for process execution, as we can still log but
don't have any fds open continously.

src/basic/log.c
src/basic/log.h

index 59bc16f..4f0fe54 100644 (file)
@@ -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 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] = {};
+                        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_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. */
@@ -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;
+}
index e3fd320..10a6032 100644 (file)
@@ -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,