From: Timo Sirainen Date: Tue, 25 May 2010 14:27:26 +0000 (+0100) Subject: Changed some index error handling conditions to log an error instead of assert-crash. X-Git-Tag: 2.0.beta6~166 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5b3b4c9159f506cdfdce7399faaeeffdf73faf7;p=thirdparty%2Fdovecot%2Fcore.git Changed some index error handling conditions to log an error instead of assert-crash. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index a6adeebe08..477cdbb865 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -192,6 +192,7 @@ mail_transaction_log_init_hdr(struct mail_transaction_log *log, struct mail_transaction_log_header *hdr) { struct mail_index *index = log->index; + struct mail_transaction_log_file *file; memset(hdr, 0, sizeof(*hdr)); hdr->major_version = MAIL_TRANSACTION_LOG_MAJOR_VERSION; @@ -226,6 +227,14 @@ mail_transaction_log_init_hdr(struct mail_transaction_log *log, } if (log->head != NULL) { + /* make sure the sequence always increases to avoid crashes + later. this catches the buggy case where two processes + happen to replace the same log file. */ + for (file = log->head->next; file != NULL; file = file->next) { + if (hdr->file_seq <= file->hdr.file_seq) + hdr->file_seq = file->hdr.file_seq + 1; + } + if (hdr->file_seq <= log->head->hdr.file_seq) { /* make sure the sequence grows */ hdr->file_seq = log->head->hdr.file_seq+1; diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c index 89cfcc169b..13fa9056e0 100644 --- a/src/lib-index/mail-transaction-log-view.c +++ b/src/lib-index/mail-transaction-log-view.c @@ -202,6 +202,16 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, } i_assert(min_file_offset >= view->tail->hdr.hdr_size); + if (min_file_seq == view->head->hdr.file_seq && + min_file_offset > view->head->sync_offset) { + /* log file offset is probably corrupted in the index file. */ + mail_transaction_log_view_set_corrupted(view, + "file_seq=%u, min_file_offset (%"PRIuUOFF_T + ") > sync_offset (%"PRIuUOFF_T")", min_file_seq, + min_file_offset, view->head->sync_offset); + return -1; + } + /* we have all of them. update refcounts. */ mail_transaction_log_view_unref_all(view); diff --git a/src/lib-storage/index/index-sync.c b/src/lib-storage/index/index-sync.c index 325d7adf9f..fc2b147b54 100644 --- a/src/lib-storage/index/index-sync.c +++ b/src/lib-storage/index/index-sync.c @@ -37,8 +37,13 @@ void index_mailbox_set_recent_uid(struct mailbox *box, uint32_t uid) struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); if (uid <= ibox->recent_flags_prev_uid) { - i_assert(seq_range_exists(&ibox->recent_flags, uid)); - return; + if (seq_range_exists(&ibox->recent_flags, uid)) + return; + + mail_storage_set_critical(box->storage, + "Recent flags state corrupted for mailbox %s", + box->vname); + array_clear(&ibox->recent_flags); } ibox->recent_flags_prev_uid = uid;