]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Changed some index error handling conditions to log an error instead of assert-crash.
authorTimo Sirainen <tss@iki.fi>
Tue, 25 May 2010 14:27:26 +0000 (15:27 +0100)
committerTimo Sirainen <tss@iki.fi>
Tue, 25 May 2010 14:27:26 +0000 (15:27 +0100)
--HG--
branch : HEAD

src/lib-index/mail-transaction-log-file.c
src/lib-index/mail-transaction-log-view.c
src/lib-storage/index/index-sync.c

index a6adeebe08dd79a84d56fc234e6859011bf25778..477cdbb8652aa2f0f414c7db9f5af4ca28b7ba4e 100644 (file)
@@ -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;
index 89cfcc169bf02d7d899b37d26a5f237d62305e32..13fa9056e05fa17fd2cfc4b542af11803624ae5b 100644 (file)
@@ -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);
 
index 325d7adf9f672dd35fc0527c769b2e4e95ba57f7..fc2b147b547d2c926ba3c65cf04beab20ec07bb4 100644 (file)
@@ -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;