]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Add more information to "Missing middle file" error.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 14:41:18 +0000 (16:41 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 15:04:34 +0000 (17:04 +0200)
src/lib-index/mail-index-modseq.c
src/lib-index/mail-transaction-log-private.h
src/lib-index/mail-transaction-log-view.c
src/lib-index/mail-transaction-log.c
src/lib-index/test-mail-transaction-log-view.c

index eeb85de119a7719fba02b34b09787484b76a0d0f..8a987a3728927bb5b1b15a1a4e20a01c1a47cf74 100644 (file)
@@ -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;
        }
index a0e0c8c988033a9743f54a7c73fdeee173c589d2..8def0da2047ee82bd878f7b4a947c763145aee5e 100644 (file)
@@ -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 */
index 2050581095391b4e1bd2201aa2e6734fab5d8287..e551d17172eb0b5db6a87963b2e60bc03beed086 100644 (file)
@@ -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++;
index 474d07154998a9b0493756db78abf22c92d114ee..fa1c9ce4dbd75607894864e7b37f1b84779a008f 100644 (file)
@@ -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;
index a49770e7056ac6ec82ec8b183df85b834c28dc74..c694cd7fc1f0902083fc3fda69c45550285fa5b1 100644 (file)
@@ -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;
 }