dovecot-2.2: lib-index: Added reason_r parameter to mail_transac...

dovecot at dovecot.org dovecot at dovecot.org
Mon Apr 6 03:08:53 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/8146fdc0de34
changeset: 18398:8146fdc0de34
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Apr 06 12:07:32 2015 +0900
description:
lib-index: Added reason_r parameter to mail_transaction_log_view_set()
This is used to improve some of the error messages about index corruption.

diffstat:

 src/doveadm/dsync/dsync-transaction-log-scan.c |  13 ++++--
 src/lib-index/mail-index-modseq.c              |   5 +-
 src/lib-index/mail-index-sync-update.c         |   8 ++-
 src/lib-index/mail-index-sync.c                |  11 +++--
 src/lib-index/mail-index-view-sync.c           |  15 ++++++-
 src/lib-index/mail-transaction-log-view.c      |  46 +++++++++++++++++++------
 src/lib-index/mail-transaction-log.h           |   2 +-
 src/lib-index/test-mail-transaction-log-view.c |  13 +++---
 src/lib-storage/mailbox-get.c                  |   5 +-
 src/lib-storage/test-mailbox-get.c             |   2 +-
 10 files changed, 81 insertions(+), 39 deletions(-)

diffs (truncated from 455 to 300 lines):

diff -r ee001c131952 -r 8146fdc0de34 src/doveadm/dsync/dsync-transaction-log-scan.c
--- a/src/doveadm/dsync/dsync-transaction-log-scan.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/doveadm/dsync/dsync-transaction-log-scan.c	Mon Apr 06 12:07:32 2015 +0900
@@ -350,6 +350,7 @@
 {
 	uint32_t log_seq, end_seq;
 	uoff_t log_offset, end_offset;
+	const char *reason;
 	bool reset;
 	int ret;
 
@@ -371,7 +372,7 @@
 		ret = mail_transaction_log_view_set(log_view,
 						    log_seq, log_offset,
 						    end_seq, end_offset,
-						    &reset);
+						    &reset, &reason);
 		if (ret != 0)
 			return ret;
 	}
@@ -390,13 +391,14 @@
 	}
 	ret = mail_transaction_log_view_set(log_view,
 					    log_seq, log_offset,
-					    end_seq, end_offset, &reset);
+					    end_seq, end_offset,
+					    &reset, &reason);
 	if (ret == 0) {
 		/* we shouldn't get here. _view_set_all() already
 		   reserved all the log files, the _view_set() only
 		   removed unwanted ones. */
-		i_error("%s: Couldn't set transaction log view (seq %u..%u)",
-			view->index->filepath, log_seq, end_seq);
+		i_error("%s: Couldn't set transaction log view (seq %u..%u): %s",
+			view->index->filepath, log_seq, end_seq, reason);
 		ret = -1;
 	}
 	if (ret < 0)
@@ -566,6 +568,7 @@
 	struct mail_transaction_log_view *log_view;
 	const struct mail_transaction_header *hdr;
 	const void *data;
+	const char *reason;
 	bool reset, found = FALSE;
 
 	i_assert(uid > 0);
@@ -578,7 +581,7 @@
 					  scan->last_log_seq,
 					  scan->last_log_offset,
 					  (uint32_t)-1, (uoff_t)-1,
-					  &reset) > 0) {
+					  &reset, &reason) > 0) {
 		while (!found &&
 		       mail_transaction_log_view_next(log_view, &hdr, &data) > 0) {
 			switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
diff -r ee001c131952 -r 8146fdc0de34 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/lib-index/mail-index-modseq.c	Mon Apr 06 12:07:32 2015 +0900
@@ -403,6 +403,7 @@
 	const struct mail_index_modseq_header *hdr;
 	const struct mail_transaction_header *thdr;
 	const void *tdata;
+	const char *reason;
 	uint32_t ext_map_idx;
 	uint32_t end_seq;
 	uoff_t end_offset;
@@ -437,12 +438,12 @@
 	ret = mail_transaction_log_view_set(ctx->log_view,
 					    I_MAX(1, hdr->log_seq),
 					    hdr->log_offset,
-					    end_seq, end_offset, &reset);
+					    end_seq, end_offset, &reset, &reason);
 	if (ret <= 0) {
 		/* missing files / error - try with only the last file */
 		ret = mail_transaction_log_view_set(ctx->log_view, end_seq, 0,
 						    end_seq, end_offset,
-						    &reset);
+						    &reset, &reason);
 		/* since we don't know if we skipped some changes, set all
 		   modseqs to beginning of the latest file. */
 		cur_modseq = mail_transaction_log_view_get_prev_modseq(
diff -r ee001c131952 -r 8146fdc0de34 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/lib-index/mail-index-sync-update.c	Mon Apr 06 12:07:32 2015 +0900
@@ -911,6 +911,7 @@
 	const void *tdata;
 	uint32_t prev_seq;
 	uoff_t start_offset, prev_offset;
+	const char *reason;
 	int ret;
 	bool had_dirty, reset;
 
@@ -952,14 +953,15 @@
 	view = mail_index_view_open_with_map(index, map);
 	ret = mail_transaction_log_view_set(view->log_view,
 					    map->hdr.log_file_seq, start_offset,
-					    (uint32_t)-1, (uoff_t)-1, &reset);
+					    (uint32_t)-1, (uoff_t)-1,
+					    &reset, &reason);
 	if (ret <= 0) {
 		mail_index_view_close(&view);
 		if (force && ret == 0) {
 			/* the seq/offset is probably broken */
 			mail_index_set_error(index, "Index %s: Lost log for "
-				"seq=%u offset=%"PRIuUOFF_T, index->filepath,
-				map->hdr.log_file_seq, start_offset);
+				"seq=%u offset=%"PRIuUOFF_T": %s", index->filepath,
+				map->hdr.log_file_seq, start_offset, reason);
 			(void)mail_index_fsck(index);
 		}
 		/* can't use it. sync by re-reading index. */
diff -r ee001c131952 -r 8146fdc0de34 src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/lib-index/mail-index-sync.c	Mon Apr 06 12:07:32 2015 +0900
@@ -284,6 +284,7 @@
 {
 	uint32_t log_seq;
 	uoff_t log_offset;
+	const char *reason;
 	bool reset;
 	int ret;
 
@@ -291,15 +292,15 @@
 
 	ret = mail_transaction_log_view_set(view->log_view,
                                             start_file_seq, start_file_offset,
-					    log_seq, log_offset, &reset);
+					    log_seq, log_offset, &reset, &reason);
 	if (ret < 0)
 		return -1;
 	if (ret == 0) {
 		/* either corrupted or the file was deleted for
 		   some reason. either way, we can't go forward */
 		mail_index_set_error(view->index,
-			"Unexpected transaction log desync with index %s",
-			view->index->filepath);
+			"Unexpected transaction log desync with index %s: %s",
+			view->index->filepath, reason);
 		return 0;
 	}
 	return 1;
@@ -529,6 +530,7 @@
 	const void *data;
 	uint32_t log_seq;
 	uoff_t log_offset;
+	const char *reason;
 	bool reset;
 	int ret;
 
@@ -544,7 +546,8 @@
 	if (mail_transaction_log_view_set(view->log_view,
 					  view->map->hdr.log_file_seq,
 					  view->map->hdr.log_file_tail_offset,
-					  log_seq, log_offset, &reset) <= 0) {
+					  log_seq, log_offset,
+					  &reset, &reason) <= 0) {
 		/* let the actual syncing handle the error */
 		return TRUE;
 	}
diff -r ee001c131952 -r 8146fdc0de34 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/lib-index/mail-index-view-sync.c	Mon Apr 06 12:07:32 2015 +0900
@@ -48,6 +48,7 @@
 	const struct mail_index_header *hdr = &view->index->map->hdr;
 	uint32_t start_seq, end_seq;
 	uoff_t start_offset, end_offset;
+	const char *reason;
 	int ret;
 
 	start_seq = view->log_file_expunge_seq;
@@ -71,7 +72,7 @@
 		ret = mail_transaction_log_view_set(view->log_view,
 						    start_seq, start_offset,
 						    end_seq, end_offset,
-						    reset_r);
+						    reset_r, &reason);
 		if (ret <= 0)
 			return ret;
 
@@ -489,7 +490,9 @@
 	struct mail_index_view *view = ctx->view;
 	uint32_t seq;
 	uoff_t offset;
+	const char *reason;
 	bool reset;
+	int ret;
 
 	/* replace the view's map */
 	view->index->map->refcount++;
@@ -501,9 +504,15 @@
 	view->log_file_head_offset = offset =
 		view->map->hdr.log_file_head_offset;
 
-	if (mail_transaction_log_view_set(view->log_view, seq, offset,
-					  seq, offset, &reset) <= 0)
+	ret = mail_transaction_log_view_set(view->log_view, seq, offset,
+					    seq, offset, &reset, &reason);
+	if (ret < 0)
 		return -1;
+	if (ret == 0) {
+		mail_index_set_error(view->index, "Failed to fix view for %s: %s",
+				     view->index->filepath, reason);
+		return 0;
+	}
 	view->inconsistent = FALSE;
 	return 0;
 }
diff -r ee001c131952 -r 8146fdc0de34 src/lib-index/mail-transaction-log-view.c
--- a/src/lib-index/mail-transaction-log-view.c	Mon Apr 06 11:39:34 2015 +0900
+++ b/src/lib-index/mail-transaction-log-view.c	Mon Apr 06 12:07:32 2015 +0900
@@ -61,7 +61,7 @@
 int mail_transaction_log_view_set(struct mail_transaction_log_view *view,
 				  uint32_t min_file_seq, uoff_t min_file_offset,
 				  uint32_t max_file_seq, uoff_t max_file_offset,
-				  bool *reset_r)
+				  bool *reset_r, const char **reason_r)
 {
 	struct mail_transaction_log_file *file, *const *files;
 	uoff_t start_offset, end_offset;
@@ -70,10 +70,12 @@
 	int ret;
 
 	*reset_r = FALSE;
+	*reason_r = NULL;
 
 	if (view->log == NULL) {
 		/* transaction log is closed already. this log view shouldn't
 		   be used anymore. */
+		*reason_r = "Log already closed";
 		return -1;
 	}
 
@@ -82,6 +84,9 @@
 		   start from the beginning */
 		if (view->log->files->hdr.prev_file_seq != 0) {
 			/* but it doesn't */
+			*reason_r = t_strdup_printf(
+				"Wanted log beginning, but found prev_file_seq=%u",
+				view->log->files->hdr.prev_file_seq);
 			return 0;
 		}
 
@@ -124,10 +129,11 @@
 
 	if (min_file_seq == max_file_seq && min_file_offset > max_file_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
+		*reason_r = t_strdup_printf(
+			"Invalid offset: file_seq=%u, min_file_offset (%"PRIuUOFF_T
 			") > max_file_offset (%"PRIuUOFF_T")",
 			min_file_seq, min_file_offset, max_file_offset);
+		mail_transaction_log_view_set_corrupted(view, "%s", *reason_r);
 		return -1;
 	}
 
@@ -142,8 +148,11 @@
 			ret = mail_transaction_log_find_file(view->log, seq,
 							     nfs_flush, &file);
 			if (ret <= 0) {
-				if (ret < 0)
+				if (ret < 0) {
+					*reason_r = t_strdup_printf(
+						"Failed to find file seq=%u", seq);
 					return -1;
+				}
 
 				/* not found / corrupted */
 				file = NULL;
@@ -166,6 +175,9 @@
 				if (file == NULL ||
 				    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)",
+						seq, min_file_seq, max_file_seq);
 					return 0;
 				}
 
@@ -198,18 +210,20 @@
 
 	if (min_file_offset < view->tail->hdr.hdr_size) {
 		/* 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
+		*reason_r = t_strdup_printf(
+			"Invalid min_file_offset: file_seq=%u, min_file_offset (%"PRIuUOFF_T
 			") < hdr_size (%u)",
 			min_file_seq, min_file_offset, view->tail->hdr.hdr_size);
+		mail_transaction_log_view_set_corrupted(view, "%s", *reason_r);
 		return -1;
 	}
 	if (max_file_offset < view->head->hdr.hdr_size) {
 		/* 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
+		*reason_r = t_strdup_printf(
+			"Invalid max_file_offset: file_seq=%u, min_file_offset (%"PRIuUOFF_T
 			") < hdr_size (%u)",
 			max_file_seq, max_file_offset, view->head->hdr.hdr_size);


More information about the dovecot-cvs mailing list