log: never block on syslog in PID 1
authorMichal Schmidt <mschmidt@redhat.com>
Sun, 18 Dec 2011 13:57:54 +0000 (14:57 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Mon, 19 Dec 2011 23:23:51 +0000 (00:23 +0100)
Use a non-blocking syslog socket if logging from PID 1.
If sendmsg fails with EAGAIN, fall back to kmsg or console only for the
current message. Next message will try syslog again.

src/log.c

index 5c5b734..4f57821 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -118,6 +118,9 @@ static int create_log_socket(int type) {
         struct timeval tv;
         int fd;
 
+        if (getpid() == 1)
+                /* systemd should not block on syslog */
+                type |= SOCK_NONBLOCK;
         if ((fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0)) < 0)
                 return -errno;
 
@@ -330,7 +333,8 @@ static int write_to_syslog(
         for (;;) {
                 ssize_t n;
 
-                if ((n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL)) < 0)
+                n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
+                if (n < 0)
                         return -errno;
 
                 if (!syslog_is_stream ||
@@ -407,8 +411,10 @@ static int log_dispatch(
                     log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
                     log_target == LOG_TARGET_SYSLOG) {
 
-                        if ((k = write_to_syslog(level, file, line, func, buffer)) < 0) {
-                                log_close_syslog();
+                        k = write_to_syslog(level, file, line, func, buffer);
+                        if (k < 0) {
+                                if (k != -EAGAIN)
+                                        log_close_syslog();
                                 log_open_kmsg();
                         } else if (k > 0)
                                 r++;
@@ -419,16 +425,19 @@ static int log_dispatch(
                      log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
                      log_target == LOG_TARGET_KMSG)) {
 
-                        if ((k = write_to_kmsg(level, file, line, func, buffer)) < 0) {
+                        k = write_to_kmsg(level, file, line, func, buffer);
+                        if (k < 0) {
                                 log_close_kmsg();
                                 log_open_console();
                         } else if (k > 0)
                                 r++;
                 }
 
-                if (k <= 0 &&
-                    (k = write_to_console(level, file, line, func, buffer)) < 0)
-                        return k;
+                if (k <= 0) {
+                        k = write_to_console(level, file, line, func, buffer);
+                        if (k < 0)
+                                return k;
+                }
 
                 buffer = e;
         } while (buffer);