Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9467:2cf9f73cf0aa HEAD
index: If we see duplicate transaction log files, avoid corrupting the newer one.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 09 Nov 2009 20:38:19 -0500 |
parents | 68af994e7f3c |
children | 7ea4e58aa356 |
files | src/lib-index/mail-transaction-log-file.c |
diffstat | 1 files changed, 33 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log-file.c Thu Nov 05 15:23:52 2009 -0500 +++ b/src/lib-index/mail-transaction-log-file.c Mon Nov 09 20:38:19 2009 -0500 @@ -15,6 +15,23 @@ #define LOG_PREFETCH 1024 #define MEMORY_LOG_NAME "(in-memory transaction log file)" +static void +mail_transaction_log_mark_corrupted(struct mail_transaction_log_file *file) +{ + unsigned int offset = + offsetof(struct mail_transaction_log_header, indexid); + + if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) + return; + + /* indexid=0 marks the log file as corrupted */ + if (pwrite_full(file->fd, &file->hdr.indexid, + sizeof(file->hdr.indexid), offset) < 0) { + mail_index_file_set_syscall_error(file->log->index, + file->filepath, "pwrite()"); + } +} + void mail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file, const char *fmt, ...) @@ -23,16 +40,7 @@ file->corrupted = TRUE; file->hdr.indexid = 0; - if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { - /* indexid=0 marks the log file as corrupted */ - if (pwrite_full(file->fd, &file->hdr.indexid, - sizeof(file->hdr.indexid), - offsetof(struct mail_transaction_log_header, - indexid)) < 0) { - mail_index_file_set_syscall_error(file->log->index, - file->filepath, "pwrite()"); - } - } + mail_transaction_log_mark_corrupted(file); va_start(va, fmt); T_BEGIN { @@ -468,10 +476,22 @@ if (f->hdr.file_seq == file->hdr.file_seq) { /* mark the old file corrupted. we can't safely remove it from the list however, so return failure. */ - mail_transaction_log_file_set_corrupted(f, + f->corrupted = TRUE; + f->hdr.indexid = 0; + if (strcmp(f->filepath, f->log->head->filepath) != 0) { + /* only mark .2 corrupted, just to make sure + we don't lose any changes from .log in case + we're somehow wrong */ + mail_transaction_log_mark_corrupted(f); + ret = 0; + } else { + ret = -1; + } + mail_index_set_error(f->log->index, + "Transaction log %s: " "duplicate transaction log sequence (%u)", - f->hdr.file_seq); - return 0; + f->filepath, f->hdr.file_seq); + return ret; } }