From: Timo Sirainen Date: Thu, 10 Jan 2013 10:12:50 +0000 (+0200) Subject: dsync: Close mail streams earlier on failures to avoid assert-crashing X-Git-Tag: 2.2.beta2~218 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f476a2abe41082176e65425358bf01bdcc86a41c;p=thirdparty%2Fdovecot%2Fcore.git dsync: Close mail streams earlier on failures to avoid assert-crashing --- diff --git a/src/doveadm/dsync/dsync-brain.c b/src/doveadm/dsync/dsync-brain.c index fa342773ed..bbdeb25f71 100644 --- a/src/doveadm/dsync/dsync-brain.c +++ b/src/doveadm/dsync/dsync-brain.c @@ -158,6 +158,7 @@ int dsync_brain_deinit(struct dsync_brain **_brain) if (dsync_ibc_has_failed(brain->ibc) || brain->state != DSYNC_STATE_DONE) brain->failed = TRUE; + dsync_ibc_close_mail_streams(brain->ibc); if (brain->box != NULL) dsync_brain_sync_mailbox_deinit(brain); diff --git a/src/doveadm/dsync/dsync-ibc-pipe.c b/src/doveadm/dsync/dsync-ibc-pipe.c index 21a966baed..f7a6b31381 100644 --- a/src/doveadm/dsync/dsync-ibc-pipe.c +++ b/src/doveadm/dsync/dsync-ibc-pipe.c @@ -434,6 +434,26 @@ dsync_ibc_pipe_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r) return DSYNC_IBC_RECV_RET_OK; } +static void pipe_close_mail_streams(struct dsync_ibc_pipe *pipe) +{ + struct item *item; + + if (array_count(&pipe->item_queue) > 0) { + item = array_idx_modifiable(&pipe->item_queue, 0); + if (item->type == ITEM_MAIL && + item->u.mail.input != NULL) + i_stream_unref(&item->u.mail.input); + } +} + +static void dsync_ibc_pipe_close_mail_streams(struct dsync_ibc *ibc) +{ + struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc; + + pipe_close_mail_streams(pipe); + pipe_close_mail_streams(pipe->remote); +} + static const struct dsync_ibc_vfuncs dsync_ibc_pipe_vfuncs = { dsync_ibc_pipe_deinit, dsync_ibc_pipe_send_handshake, @@ -453,6 +473,7 @@ static const struct dsync_ibc_vfuncs dsync_ibc_pipe_vfuncs = { dsync_ibc_pipe_recv_mail_request, dsync_ibc_pipe_send_mail, dsync_ibc_pipe_recv_mail, + dsync_ibc_pipe_close_mail_streams, dsync_ibc_pipe_is_send_queue_full, dsync_ibc_pipe_has_pending_data }; diff --git a/src/doveadm/dsync/dsync-ibc-private.h b/src/doveadm/dsync/dsync-ibc-private.h index 09ccea4db9..0871f06d04 100644 --- a/src/doveadm/dsync/dsync-ibc-private.h +++ b/src/doveadm/dsync/dsync-ibc-private.h @@ -61,6 +61,7 @@ struct dsync_ibc_vfuncs { (*recv_mail)(struct dsync_ibc *ibc, struct dsync_mail **mail_r); + void (*close_mail_streams)(struct dsync_ibc *ibc); bool (*is_send_queue_full)(struct dsync_ibc *ibc); bool (*has_pending_data)(struct dsync_ibc *ibc); }; diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index d1b45588df..68fdcfebe8 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -1489,6 +1489,16 @@ dsync_ibc_stream_recv_mail(struct dsync_ibc *_ibc, struct dsync_mail **mail_r) return DSYNC_IBC_RECV_RET_OK; } +static void dsync_ibc_stream_close_mail_streams(struct dsync_ibc *_ibc) +{ + struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; + + if (ibc->mail_output != NULL) { + i_stream_unref(&ibc->mail_output); + dsync_ibc_stream_stop(ibc); + } +} + static bool dsync_ibc_stream_is_send_queue_full(struct dsync_ibc *_ibc) { struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc; @@ -1531,6 +1541,7 @@ static const struct dsync_ibc_vfuncs dsync_ibc_stream_vfuncs = { dsync_ibc_stream_recv_mail_request, dsync_ibc_stream_send_mail, dsync_ibc_stream_recv_mail, + dsync_ibc_stream_close_mail_streams, dsync_ibc_stream_is_send_queue_full, dsync_ibc_stream_has_pending_data }; diff --git a/src/doveadm/dsync/dsync-ibc.c b/src/doveadm/dsync/dsync-ibc.c index 7db6322f05..faba4ca1e6 100644 --- a/src/doveadm/dsync/dsync-ibc.c +++ b/src/doveadm/dsync/dsync-ibc.c @@ -178,6 +178,11 @@ dsync_ibc_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r) return ibc->v.recv_mail(ibc, mail_r); } +void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc) +{ + ibc->v.close_mail_streams(ibc); +} + bool dsync_ibc_has_failed(struct dsync_ibc *ibc) { return ibc->failed; diff --git a/src/doveadm/dsync/dsync-ibc.h b/src/doveadm/dsync/dsync-ibc.h index 7d9ecd2b59..8ab753e552 100644 --- a/src/doveadm/dsync/dsync-ibc.h +++ b/src/doveadm/dsync/dsync-ibc.h @@ -110,6 +110,10 @@ dsync_ibc_send_mail(struct dsync_ibc *ibc, const struct dsync_mail *mail); enum dsync_ibc_recv_ret dsync_ibc_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r); +/* Close any mail input streams that are kept open. This needs to be called + before the mail is attempted to be freed (usually on error conditions). */ +void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc); + bool dsync_ibc_has_failed(struct dsync_ibc *ibc); bool dsync_ibc_is_send_queue_full(struct dsync_ibc *ibc); bool dsync_ibc_has_pending_data(struct dsync_ibc *ibc);