]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm-server: Switch to TCP connection's ioloop while sending logs to remote
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 27 Nov 2017 16:26:00 +0000 (18:26 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 30 Nov 2017 23:09:42 +0000 (01:09 +0200)
Fixes:
Warning: I/O leak: 0x558d7c074ed0 (ostream-file.c:349, fd 16)
Panic: file ioloop.c: line 127 (io_remove_full): assertion failed: (io->callback != NULL)

src/doveadm/client-connection-tcp.c

index c75757dafbba1100d71416730ea7a2b2b51f4974..f084fe96355ebb94162fc4b757840cf6f267ad43 100644 (file)
@@ -32,6 +32,7 @@ struct client_connection_tcp {
        struct ostream *output;
        struct ostream *log_out;
        struct ssl_iostream *ssl_iostream;
+       struct ioloop *ioloop;
 
        bool handshaked:1;
        bool preauthenticated:1;
@@ -64,6 +65,7 @@ doveadm_server_log_handler(const struct failure_context *ctx,
 
        if (!log_recursing && conn != NULL &&
            conn->log_out != NULL) T_BEGIN {
+               struct ioloop *prev_ioloop = current_ioloop;
                struct ostream *log_out = conn->log_out;
                char c;
                const char *ptr, *start;
@@ -74,6 +76,10 @@ doveadm_server_log_handler(const struct failure_context *ctx,
                   any of the following code causes logging */
                log_recursing = TRUE;
 
+               /* since we can get here from just about anywhere, make sure
+                  the log ostream uses the connection's ioloop. */
+               io_loop_set_current(conn->ioloop);
+
                c = doveadm_log_type_to_char(ctx->type);
                corked = o_stream_is_corked(log_out);
 
@@ -98,6 +104,7 @@ doveadm_server_log_handler(const struct failure_context *ctx,
                o_stream_uncork(log_out);
                if (corked)
                        o_stream_cork(log_out);
+               io_loop_set_current(prev_ioloop);
 
                log_recursing = FALSE;
        } T_END;
@@ -299,7 +306,7 @@ static int doveadm_cmd_handle(struct client_connection_tcp *conn,
                              int argc, const char *const argv[],
                              struct doveadm_cmd_context *cctx)
 {
-       struct ioloop *ioloop, *prev_ioloop = current_ioloop;
+       struct ioloop *prev_ioloop = current_ioloop;
        const struct doveadm_cmd *cmd = NULL;
        const struct doveadm_mail_cmd *mail_cmd;
        struct doveadm_mail_cmd_context *mctx;
@@ -326,7 +333,7 @@ static int doveadm_cmd_handle(struct client_connection_tcp *conn,
        /* some commands will want to call io_loop_run(), but we're already
           running one and we can't call the original one recursively, so
           create a new ioloop. */
-       ioloop = io_loop_create();
+       conn->ioloop = io_loop_create();
 
        if (cmd_ver2 != NULL)
                doveadm_cmd_server_run_ver2(conn, argc, argv, cctx);
@@ -339,8 +346,8 @@ static int doveadm_cmd_handle(struct client_connection_tcp *conn,
        o_stream_switch_ioloop(conn->output);
        if (conn->log_out != NULL)
                o_stream_switch_ioloop(conn->log_out);
-       io_loop_set_current(ioloop);
-       io_loop_destroy(&ioloop);
+       io_loop_set_current(conn->ioloop);
+       io_loop_destroy(&conn->ioloop);
 
        /* clear all headers */
        doveadm_print_deinit();