chiark / gitweb /
core: synchronously block when logging
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Jul 2013 05:24:05 +0000 (07:24 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 24 Jul 2013 10:34:28 +0000 (12:34 +0200)
Previously, the logging sockets were asynchronous and if clogged we'd
lose messages. We did this to be extra careful given that PID 1 might
need to spawn the logging daemon as response to PID 1's own log messages
and we really should avoid a deadlock in that case.

As it turns out this causes loss of too many messages, hence make the
socket blocking again, however put a time limit on it to avoid unbounded
deadlocks in the unlikely case they happen.

https://bugs.freedesktop.org/show_bug.cgi?id=66664

src/shared/log.c

index 27317f7..8f4995a 100644 (file)
@@ -115,16 +115,20 @@ void log_close_syslog(void) {
 
 static int create_log_socket(int type) {
         int fd;
+        struct timeval tv;
 
-        /* All output to the syslog/journal fds we do asynchronously,
-         * and if the buffers are full we just drop the messages */
-
-        fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
         if (fd < 0)
                 return -errno;
 
         fd_inc_sndbuf(fd, SNDBUF_SIZE);
 
+        /* We need a blocking fd here since we'd otherwise lose
+        messages way too early. However, let's not hang forever in the
+        unlikely case of a deadlock. */
+        timeval_store(&tv, 1*USEC_PER_MINUTE);
+        setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+
         return fd;
 }