]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal-gatewayd: timeout journal wait to allow thread cleanup 2144/head 2287/head
authorDan Dedrick <ddedrick@lexmark.com>
Thu, 10 Dec 2015 21:13:24 +0000 (16:13 -0500)
committerDan Dedrick <ddedrick@lexmark.com>
Mon, 14 Dec 2015 13:50:07 +0000 (08:50 -0500)
When a client connects with follow=1 and then disconnects we can get
stuck in sd_journal_wait indefinitely if no journal messages are logged.
Every time a client does this another thread is allocated and these
continue to stack until either a journal message is logged or we run out
of mapping to put a stack in.

By adding a timeout if we don't see any journal messages in that timeout
we will simply pop back out to microhttpd which will sanity check the
connection for us and if it is still connected pop us back into the wait
for more journal messages.

src/journal-remote/journal-gatewayd.c

index 006791a542186e0e8af7cc1b53a6c85df40e5aca..4e96fb0a4d1d0f8dd9ede2736f86ae995cfe7914 100644 (file)
@@ -45,6 +45,8 @@
 #include "sigbus.h"
 #include "util.h"
 
+#define JOURNAL_WAIT_TIMEOUT (10*USEC_PER_SEC)
+
 static char *arg_key_pem = NULL;
 static char *arg_cert_pem = NULL;
 static char *arg_trust_pem = NULL;
@@ -181,11 +183,13 @@ static ssize_t request_reader_entries(
                 } else if (r == 0) {
 
                         if (m->follow) {
-                                r = sd_journal_wait(m->journal, (uint64_t) -1);
+                                r = sd_journal_wait(m->journal, (uint64_t) JOURNAL_WAIT_TIMEOUT);
                                 if (r < 0) {
                                         log_error_errno(r, "Couldn't wait for journal event: %m");
                                         return MHD_CONTENT_READER_END_WITH_ERROR;
                                 }
+                                if (r == SD_JOURNAL_NOP)
+                                        break;
 
                                 continue;
                         }
@@ -241,6 +245,8 @@ static ssize_t request_reader_entries(
         }
 
         n = m->size - pos;
+        if (n < 1)
+                return 0;
         if (n > max)
                 n = max;