changeset 21171:d3022316712b

lib-index: Add more information to "Missing middle file" error.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 18 Nov 2016 16:41:18 +0200
parents 0edde4c50a1d
children 5ef269356b27
files 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
diffstat 5 files changed, 46 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-modseq.c	Fri Nov 18 16:27:33 2016 +0200
+++ b/src/lib-index/mail-index-modseq.c	Fri Nov 18 16:41:18 2016 +0200
@@ -695,6 +695,7 @@
 {
 	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 @@
 	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;
 	}
--- a/src/lib-index/mail-transaction-log-private.h	Fri Nov 18 16:27:33 2016 +0200
+++ b/src/lib-index/mail-transaction-log-private.h	Fri Nov 18 16:41:18 2016 +0200
@@ -123,7 +123,8 @@
 
 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 */
--- a/src/lib-index/mail-transaction-log-view.c	Fri Nov 18 16:27:33 2016 +0200
+++ b/src/lib-index/mail-transaction-log-view.c	Fri Nov 18 16:41:18 2016 +0200
@@ -154,6 +154,8 @@
 
 	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 @@
 				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 @@
 		}
 
 		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 @@
 				    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_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 @@
 				     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++;
--- a/src/lib-index/mail-transaction-log.c	Fri Nov 18 16:27:33 2016 +0200
+++ b/src/lib-index/mail-transaction-log.c	Fri Nov 18 16:41:18 2016 +0200
@@ -364,7 +364,8 @@
 
 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 @@
 		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 @@
 		}
 	}
 
-	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;
--- a/src/lib-index/test-mail-transaction-log-view.c	Fri Nov 18 16:27:33 2016 +0200
+++ b/src/lib-index/test-mail-transaction-log-view.c	Fri Nov 18 16:41:18 2016 +0200
@@ -20,7 +20,8 @@
 
 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 @@
 			return 1;
 		}
 	}
+	*reason_r = "not found";
 	return 0;
 }