dovecot-1.2: Write CPU endianess to transaction log header and c...

dovecot at dovecot.org dovecot at dovecot.org
Sun Aug 31 09:31:31 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/612eb505775f
changeset: 8129:612eb505775f
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Aug 31 09:31:27 2008 +0300
description:
Write CPU endianess to transaction log header and check it's correct when reading.

diffstat:

3 files changed, 52 insertions(+), 8 deletions(-)
src/lib-index/mail-transaction-log-file.c |   52 +++++++++++++++++++++++++----
src/lib-index/mail-transaction-log.h      |    7 ++-
src/util/logview.c                        |    1 

diffs (123 lines):

diff -r fcf0c5ac5975 -r 612eb505775f src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Sat Aug 30 15:24:55 2008 +0300
+++ b/src/lib-index/mail-transaction-log-file.c	Sun Aug 31 09:31:27 2008 +0300
@@ -180,6 +180,9 @@ mail_transaction_log_init_hdr(struct mai
 	hdr->hdr_size = sizeof(struct mail_transaction_log_header);
 	hdr->indexid = log->index->indexid;
 	hdr->create_stamp = ioloop_time;
+#ifndef WORDS_BIGENDIAN
+	hdr->compat_flags |= MAIL_INDEX_COMPAT_LITTLE_ENDIAN;
+#endif
 
 	if (index->fd != -1) {
 		/* not creating index - make sure we have latest header */
@@ -345,6 +348,27 @@ void mail_transaction_log_file_unlock(st
 	file_unlock(&file->file_lock);
 }
 
+static ssize_t
+mail_transaction_log_file_read_header(struct mail_transaction_log_file *file)
+{
+	ssize_t pos;
+	int ret;
+
+	memset(&file->hdr, 0, sizeof(file->hdr));
+
+        /* try to read the whole header, but it's not necessarily an error to
+	   read less since the older versions of the log format could be
+	   smaller. */
+        pos = 0;
+	do {
+		ret = pread(file->fd, PTR_OFFSET(&file->hdr, pos),
+			    sizeof(file->hdr) - pos, pos);
+		if (ret > 0)
+			pos += ret;
+	} while (ret > 0 && pos < (ssize_t)sizeof(file->hdr));
+	return ret < 0 ? -1 : pos;
+}
+
 static int
 mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file,
 				   bool ignore_estale)
@@ -357,24 +381,40 @@ mail_transaction_log_file_read_hdr(struc
 	if (file->corrupted)
 		return 0;
 
-	ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0);
+	ret = mail_transaction_log_file_read_header(file);
 	if (ret < 0) {
                 if (errno != ESTALE || !ignore_estale) {
                         mail_index_file_set_syscall_error(file->log->index,
                                                           file->filepath,
-                                                          "pread_full()");
+                                                          "pread()");
                 }
 		return -1;
 	}
-	if (ret == 0) {
+	if (file->hdr.major_version != MAIL_TRANSACTION_LOG_MAJOR_VERSION) {
+		/* incompatible version - fix silently */
+		return 0;
+	}
+	if (ret < MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE) {
 		mail_transaction_log_file_set_corrupted(file,
 			"unexpected end of file while reading header");
 		return 0;
 	}
 
-	if (file->hdr.major_version != MAIL_TRANSACTION_LOG_MAJOR_VERSION) {
-		/* incompatible version - fix silently */
-		return 0;
+	if (file->hdr.minor_version >= 2 || file->hdr.major_version > 1) {
+		/* we have compatibility flags */
+		enum mail_index_header_compat_flags compat_flags = 0;
+
+#ifndef WORDS_BIGENDIAN
+		compat_flags |= MAIL_INDEX_COMPAT_LITTLE_ENDIAN;
+#endif
+		if (file->hdr.compat_flags != compat_flags) {
+			/* architecture change */
+			mail_index_set_error(file->log->index,
+					     "Rebuilding index file %s: "
+					     "CPU architecture changed",
+					     file->log->index->filepath);
+			return 0;
+		}
 	}
 	if (file->hdr.hdr_size < MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE) {
 		mail_transaction_log_file_set_corrupted(file,
diff -r fcf0c5ac5975 -r 612eb505775f src/lib-index/mail-transaction-log.h
--- a/src/lib-index/mail-transaction-log.h	Sat Aug 30 15:24:55 2008 +0300
+++ b/src/lib-index/mail-transaction-log.h	Sun Aug 31 09:31:27 2008 +0300
@@ -5,7 +5,7 @@ struct mail_index_transaction;
 struct mail_index_transaction;
 
 #define MAIL_TRANSACTION_LOG_MAJOR_VERSION 1
-#define MAIL_TRANSACTION_LOG_MINOR_VERSION 1
+#define MAIL_TRANSACTION_LOG_MINOR_VERSION 2
 #define MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE 24
 
 struct mail_transaction_log_header {
@@ -18,7 +18,10 @@ struct mail_transaction_log_header {
 	uint32_t prev_file_seq;
 	uint32_t prev_file_offset;
 	uint32_t create_stamp;
-	uint64_t initial_modseq;
+	uint64_t initial_modseq; /* v1.1+ */
+
+	uint8_t compat_flags; /* enum mail_index_header_compat_flags, v1.2+ */
+	uint8_t unused[3];
 };
 
 enum mail_transaction_type {
diff -r fcf0c5ac5975 -r 612eb505775f src/util/logview.c
--- a/src/util/logview.c	Sat Aug 30 15:24:55 2008 +0300
+++ b/src/util/logview.c	Sun Aug 31 09:31:27 2008 +0300
@@ -45,6 +45,7 @@ static void dump_hdr(int fd, uint64_t *m
 	printf("create stamp = %u\n", hdr.create_stamp);
 	printf("initial modseq = %llu\n",
 	       (unsigned long long)hdr.initial_modseq);
+	printf("compat flags = %x\n", hdr.compat_flags);
 	*modseq_r = hdr.initial_modseq;
 }
 


More information about the dovecot-cvs mailing list