]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: When log writing keeps returning EAGAIN, change process title only once
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 18 Jun 2018 14:03:01 +0000 (17:03 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 18 Jun 2018 18:12:12 +0000 (21:12 +0300)
Otherwise each call will use up data stack memory.

src/lib/failures.c

index 1b7f3004403bd8720b6efa2efab7e7a9f8c1491f..078b0ed0158864357ffc785ef9faa8435c00779e 100644 (file)
@@ -127,8 +127,11 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len)
        ssize_t ret;
        unsigned int prev_signal_term_counter = signal_term_counter;
        unsigned int terminal_eintr_count = 0;
+       const char *old_title = NULL;
+       bool failed = FALSE, process_title_changed = FALSE;
 
-       while ((ret = write(fd, data, len)) != (ssize_t)len) {
+       while (!failed &&
+              (ret = write(fd, data, len)) != (ssize_t)len) {
                if (ret > 0) {
                        /* some was written, continue.. */
                        data += ret;
@@ -138,7 +141,8 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len)
                if (ret == 0) {
                        /* out of disk space? */
                        errno = ENOSPC;
-                       return -1;
+                       failed = TRUE;
+                       break;
                }
                switch (errno) {
                case EAGAIN: {
@@ -152,17 +156,19 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len)
                           all the processes see the change. To avoid problems,
                           we'll wait using poll() instead of changing the
                           O_NONBLOCK flag. */
-                       const char *title, *old_title =
-                               t_strdup(process_title_get());
-
-                       if (old_title == NULL)
-                               title = "[blocking on log write]";
-                       else
-                               title = t_strdup_printf("%s - [blocking on log write]",
-                                                       old_title);
-                       process_title_set(title);
+                       if (!process_title_changed) {
+                               const char *title;
+
+                               process_title_changed = TRUE;
+                               old_title = t_strdup(process_title_get());
+                               if (old_title == NULL)
+                                       title = "[blocking on log write]";
+                               else
+                                       title = t_strdup_printf("%s - [blocking on log write]",
+                                                               old_title);
+                               process_title_set(title);
+                       }
                        fd_wait_writable(fd);
-                       process_title_set(old_title);
                        break;
                }
                case EINTR:
@@ -174,15 +180,19 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len)
                        } else {
                                /* received two terminal signals.
                                   someone wants us dead. */
-                               return -1;
+                               failed = TRUE;
+                               break;
                        }
                        break;
                default:
-                       return -1;
+                       failed = TRUE;
+                       break;
                }
                prev_signal_term_counter = signal_term_counter;
        }
-       return 0;
+       if (process_title_changed)
+               process_title_set(old_title);
+       return failed ? -1 : 0;
 }
 
 static int ATTR_FORMAT(3, 0)