chiark / gitweb /
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 5c5b734f2f83c96a9bf7cb18cfdf89e630dbea0e..4f57821da3a97ca91efe17302be7c9fbb4333a63 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);