]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
log: Log a warning for each service that still has processes at shutdown
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 24 Aug 2017 14:01:34 +0000 (17:01 +0300)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Fri, 25 Aug 2017 12:21:11 +0000 (15:21 +0300)
This makes it clearer which services are causing log process to hang, and
also which processes may have their logging discarded afterwards.

src/log/log-connection.c

index b300a87ee9d79867d333b1ac0c4aa38b72c944aa..e687705e5a1da95cdfe7a25e90800dcdf2762ce8 100644 (file)
@@ -54,7 +54,8 @@ static ARRAY(struct log_connection *) logs_by_fd;
 static unsigned int global_pending_count;
 static struct log_connection *last_pending_log;
 
-static void log_connection_destroy(struct log_connection *log);
+static void
+log_connection_destroy(struct log_connection *log, bool shutting_down);
 
 static void log_refresh_proctitle(void)
 {
@@ -337,7 +338,7 @@ static void log_connection_input(struct log_connection *log)
 
        if (!log->handshaked) {
                if (log_connection_handshake(log) < 0) {
-                       log_connection_destroy(log);
+                       log_connection_destroy(log, FALSE);
                        return;
                }
                /* come back here even if we read something else besides a
@@ -364,7 +365,7 @@ static void log_connection_input(struct log_connection *log)
        if (log->input->eof) {
                if (log->input->stream_errno != 0)
                        i_error("read(log %s) failed: %m", log->default_prefix);
-               log_connection_destroy(log);
+               log_connection_destroy(log, FALSE);
        } else {
                i_assert(!log->input->closed);
                if (!too_much) {
@@ -410,22 +411,31 @@ void log_connection_create(struct log_error_buffer *errorbuf,
        log_connection_input(log);
 }
 
-static void log_connection_destroy(struct log_connection *log)
+static void
+log_connection_destroy(struct log_connection *log, bool shutting_down)
 {
        struct hash_iterate_context *iter;
        void *key;
        struct log_client *client;
+       unsigned int client_count = 0;
 
        array_idx_clear(&logs_by_fd, log->listen_fd);
 
        DLLIST_REMOVE(&log_connections, log);
 
        iter = hash_table_iterate_init(log->clients);
-       while (hash_table_iterate(iter, log->clients, &key, &client))
+       while (hash_table_iterate(iter, log->clients, &key, &client)) {
                i_free(client);
+               client_count++;
+       }
        hash_table_iterate_deinit(&iter);
        hash_table_destroy(&log->clients);
 
+       if (client_count > 0 && shutting_down) {
+               i_warning("Shutting down logging for '%s' with %u clients",
+                         log->default_prefix, client_count);
+       }
+
        i_stream_unref(&log->input);
        if (log->io != NULL)
                io_remove(&log->io);
@@ -447,6 +457,6 @@ void log_connections_deinit(void)
        /* normally we don't exit until all log connections are gone,
           but we could get here when we're being killed by a signal */
        while (log_connections != NULL)
-               log_connection_destroy(log_connections);
+               log_connection_destroy(log_connections, TRUE);
        array_free(&logs_by_fd);
 }