From: Timo Sirainen Date: Fri, 18 Nov 2016 14:41:18 +0000 (+0200) Subject: lib-index: Add more information to "Missing middle file" error. X-Git-Tag: 2.2.27~97 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=704657e1c492c729a7c9955f53c76ac2cedb9ed6;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Add more information to "Missing middle file" error. --- diff --git a/src/lib-index/mail-index-modseq.c b/src/lib-index/mail-index-modseq.c index eeb85de119..8a987a3728 100644 --- a/src/lib-index/mail-index-modseq.c +++ b/src/lib-index/mail-index-modseq.c @@ -695,6 +695,7 @@ bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view, { struct mail_transaction_log *log = view->index->log; struct mail_transaction_log_file *file, *prev_file; + const char *reason; int ret; if (log->files == NULL) { @@ -704,7 +705,7 @@ bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view, while (modseq < log->files->hdr.initial_modseq) { /* try to find the previous log file if it still exists */ ret = mail_transaction_log_find_file(log, - log->files->hdr.file_seq - 1, FALSE, &file); + log->files->hdr.file_seq - 1, FALSE, &file, &reason); if (ret <= 0) return FALSE; } diff --git a/src/lib-index/mail-transaction-log-private.h b/src/lib-index/mail-transaction-log-private.h index a0e0c8c988..8def0da204 100644 --- a/src/lib-index/mail-transaction-log-private.h +++ b/src/lib-index/mail-transaction-log-private.h @@ -123,7 +123,8 @@ int mail_transaction_log_file_lock(struct mail_transaction_log_file *file); int mail_transaction_log_find_file(struct mail_transaction_log *log, uint32_t file_seq, bool nfs_flush, - struct mail_transaction_log_file **file_r); + struct mail_transaction_log_file **file_r, + const char **reason_r); /* Returns 1 if ok, 0 if file is corrupted or offset range is invalid, -1 if I/O error */ diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c index 2050581095..e551d17172 100644 --- a/src/lib-index/mail-transaction-log-view.c +++ b/src/lib-index/mail-transaction-log-view.c @@ -154,6 +154,8 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, view->tail = view->head = file = NULL; for (seq = min_file_seq; seq <= max_file_seq; seq++) { + const char *reason = NULL; + if (file == NULL || file->hdr.file_seq != seq) { /* see if we could find the missing file. if we know the max. file sequence or we don't have the the min. @@ -163,11 +165,12 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, max_file_seq != (uint32_t)-1; ret = mail_transaction_log_find_file(view->log, seq, - nfs_flush, &file); + nfs_flush, &file, &reason); if (ret <= 0) { if (ret < 0) { *reason_r = t_strdup_printf( - "Failed to find file seq=%u", seq); + "Failed to find file seq=%u: %s", + seq, reason); return -1; } @@ -177,6 +180,7 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, } if (file == NULL || file->hdr.file_seq != seq) { + i_assert(reason != NULL); if (file == NULL && max_file_seq == (uint32_t)-1 && view->head == view->log->head) { /* we just wanted to sync everything */ @@ -193,9 +197,9 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, file->hdr.file_seq > max_file_seq) { /* missing files in the middle */ *reason_r = t_strdup_printf( - "Missing middle file seq=%u (between %u..%u, we have seqs %s)", + "Missing middle file seq=%u (between %u..%u, we have seqs %s): %s", seq, min_file_seq, max_file_seq, - mail_transaction_log_get_file_seqs(view->log)); + mail_transaction_log_get_file_seqs(view->log), reason); return 0; } @@ -342,9 +346,10 @@ int mail_transaction_log_view_set(struct mail_transaction_log_view *view, int mail_transaction_log_view_set_all(struct mail_transaction_log_view *view) { struct mail_transaction_log_file *file, *first; + const char *reason; /* make sure .log.2 file is opened */ - (void)mail_transaction_log_find_file(view->log, 1, FALSE, &file); + (void)mail_transaction_log_find_file(view->log, 1, FALSE, &file, &reason); first = view->log->files; i_assert(first != NULL); @@ -388,11 +393,12 @@ void mail_transaction_log_view_clear(struct mail_transaction_log_view *view, uint32_t oldest_file_seq) { struct mail_transaction_log_file *file; + const char *reason; mail_transaction_log_view_unref_all(view); if (oldest_file_seq != 0 && mail_transaction_log_find_file(view->log, oldest_file_seq, FALSE, - &file) > 0) { + &file, &reason) > 0) { for (; file != NULL; file = file->next) { array_append(&view->file_refs, &file, 1); file->refcount++; diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index 474d071549..fa1c9ce4db 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -364,7 +364,8 @@ void mail_transaction_log_set_mailbox_sync_pos(struct mail_transaction_log *log, int mail_transaction_log_find_file(struct mail_transaction_log *log, uint32_t file_seq, bool nfs_flush, - struct mail_transaction_log_file **file_r) + struct mail_transaction_log_file **file_r, + const char **reason_r) { struct mail_transaction_log_file *file; int ret; @@ -374,19 +375,29 @@ int mail_transaction_log_find_file(struct mail_transaction_log *log, if (log->head->locked) { /* transaction log is locked. there's no way a newer file exists. */ + *reason_r = "Log is locked - newer log can't exist"; return 0; } - if (mail_transaction_log_refresh(log, FALSE) < 0) + if (mail_transaction_log_refresh(log, FALSE) < 0) { + *reason_r = "Log refresh failed"; return -1; + } if (file_seq > log->head->hdr.file_seq) { - if (!nfs_flush || !log->nfs_flush) + if (!nfs_flush || !log->nfs_flush) { + *reason_r = "Requested newer log than exists"; return 0; + } /* try again, this time flush attribute cache */ - if (mail_transaction_log_refresh(log, TRUE) < 0) + if (mail_transaction_log_refresh(log, TRUE) < 0) { + *reason_r = "Log refresh with NFS flush failed"; return -1; - if (file_seq > log->head->hdr.file_seq) + } + if (file_seq > log->head->hdr.file_seq) { + *reason_r = "Requested newer log than exists - " + "still after NFS flush"; return 0; + } } } @@ -397,19 +408,28 @@ int mail_transaction_log_find_file(struct mail_transaction_log *log, } } - if (MAIL_INDEX_IS_IN_MEMORY(log->index)) + if (MAIL_INDEX_IS_IN_MEMORY(log->index)) { + *reason_r = "Logs are only in memory"; return 0; + } /* see if we have it in log.2 file */ file = mail_transaction_log_file_alloc(log, log->filepath2); if ((ret = mail_transaction_log_file_open(file)) <= 0) { mail_transaction_log_file_free(&file); + if (ret < 0) + *reason_r = "Failed to open .log.2"; + else + *reason_r = ".log.2 doesn't exist"; return ret; } /* but is it what we expected? */ - if (file->hdr.file_seq != file_seq) + if (file->hdr.file_seq != file_seq) { + *reason_r = t_strdup_printf(".log.2 contains file_seq=%u", + file->hdr.file_seq); return 0; + } *file_r = file; return 1; diff --git a/src/lib-index/test-mail-transaction-log-view.c b/src/lib-index/test-mail-transaction-log-view.c index a49770e705..c694cd7fc1 100644 --- a/src/lib-index/test-mail-transaction-log-view.c +++ b/src/lib-index/test-mail-transaction-log-view.c @@ -20,7 +20,8 @@ void mail_transaction_logs_clean(struct mail_transaction_log *log ATTR_UNUSED) int mail_transaction_log_find_file(struct mail_transaction_log *log, uint32_t file_seq, bool nfs_flush ATTR_UNUSED, - struct mail_transaction_log_file **file_r) + struct mail_transaction_log_file **file_r, + const char **reason_r) { struct mail_transaction_log_file *file; @@ -30,6 +31,7 @@ int mail_transaction_log_find_file(struct mail_transaction_log *log, return 1; } } + *reason_r = "not found"; return 0; }