[dovecot-cvs] dovecot/src/lib-index mail-index-sync.c, 1.5, 1.6 mail-index-view-sync.c, 1.3, 1.4 mail-transaction-log-view.c, 1.6, 1.7 mail-transaction-log.c, 1.12, 1.13 mail-transaction-log.h, 1.3, 1.4

cras at procontrol.fi cras at procontrol.fi
Sat May 1 18:32:26 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv19818/lib-index

Modified Files:
	mail-index-sync.c mail-index-view-sync.c 
	mail-transaction-log-view.c mail-transaction-log.c 
	mail-transaction-log.h 
Log Message:
automatically fix broken/missing transaction log files on the fly



Index: mail-index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mail-index-sync.c	1 May 2004 14:30:37 -0000	1.5
+++ mail-index-sync.c	1 May 2004 15:32:24 -0000	1.6
@@ -399,6 +399,7 @@
 
 int mail_index_sync_end(struct mail_index_sync_ctx *ctx)
 {
+	const struct mail_index_header *hdr;
 	uint32_t seq;
 	uoff_t offset;
 	int ret = 0;
@@ -408,12 +409,14 @@
 
 	mail_transaction_log_get_head(ctx->index->log, &seq, &offset);
 
-	if (mail_transaction_log_view_set(ctx->view->log_view,
-					  ctx->index->hdr->log_file_seq,
-					  ctx->index->hdr->log_file_offset,
-					  seq, offset,
-					  MAIL_TRANSACTION_TYPE_MASK) < 0)
-		ret = -1;
+	if (ret == 0) {
+		hdr = ctx->index->hdr;
+		mail_transaction_log_view_unset(ctx->view->log_view);
+		if (mail_transaction_log_view_set(ctx->view->log_view,
+				hdr->log_file_seq, hdr->log_file_offset,
+				seq, offset, MAIL_TRANSACTION_TYPE_MASK) < 0)
+			ret = -1;
+	}
 
 	if (ret == 0) {
 		mail_index_sync_read_and_sort(ctx, TRUE);
@@ -423,9 +426,8 @@
 
 	mail_index_unlock(ctx->index, ctx->lock_id);
 	mail_transaction_log_sync_unlock(ctx->index->log);
+	mail_index_view_close(ctx->view);
 
-	if (ctx->view != NULL)
-		mail_index_view_close(ctx->view);
 	if (ctx->expunges_buf != NULL)
 		buffer_free(ctx->expunges_buf);
 	if (ctx->updates_buf != NULL)

Index: mail-index-view-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mail-index-view-sync.c	1 May 2004 14:30:37 -0000	1.3
+++ mail-index-view-sync.c	1 May 2004 15:32:24 -0000	1.4
@@ -50,6 +50,7 @@
 		buffer_append(*expunges_r, &exp->seq1, sizeof(exp->seq1));
 		buffer_append(*expunges_r, &exp->seq2, sizeof(exp->seq2));
 	}
+        mail_transaction_log_view_unset(view->log_view);
 	return 0;
 }
 
@@ -315,6 +316,8 @@
 	mail_index_unmap(view->index, view->map);
 	view->map = ctx->sync_map;
 
+        mail_transaction_log_view_unset(view->log_view);
+
 	if (ctx->expunges != NULL)
 		buffer_free(ctx->expunges);
 

Index: mail-transaction-log-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mail-transaction-log-view.c	1 May 2004 14:30:37 -0000	1.6
+++ mail-transaction-log-view.c	1 May 2004 15:32:24 -0000	1.7
@@ -34,6 +34,7 @@
 
 	view = i_new(struct mail_transaction_log_view, 1);
 	view->log = log;
+	view->broken = TRUE;
 	view->expunges_buf =
 		buffer_create_dynamic(default_pool, 512, (size_t)-1);
 
@@ -42,24 +43,9 @@
 	return view;
 }
 
-static void
-mail_transaction_log_view_close_files(struct mail_transaction_log_view *view)
-{
-	struct mail_transaction_log_file *file;
-
-	for (file = view->log->tail; file != NULL; file = file->next) {
-		if (file->hdr.file_seq > view->max_file_seq)
-			break;
-		if (file->hdr.file_seq >= view->min_file_seq)
-			file->refcount--;
-	}
-
-	mail_transaction_logs_clean(view->log);
-}
-
 void mail_transaction_log_view_close(struct mail_transaction_log_view *view)
 {
-	mail_transaction_log_view_close_files(view);
+	mail_transaction_log_view_unset(view);
 	if (view->data_buf != NULL)
 		buffer_free(view->data_buf);
 	buffer_free(view->expunges_buf);
@@ -79,14 +65,11 @@
 	uoff_t end_offset;
 	int ret;
 
+	i_assert(view->broken);
 	i_assert(min_file_seq <= max_file_seq);
 	i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
 	i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
 
-	view->broken = TRUE;
-
-        mail_transaction_log_view_close_files(view);
-
 	ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
 	if (ret <= 0) {
 		if (ret == 0 &&
@@ -161,6 +144,24 @@
 	return 0;
 }
 
+void mail_transaction_log_view_unset(struct mail_transaction_log_view *view)
+{
+	struct mail_transaction_log_file *file;
+
+	if (view->broken)
+		return;
+
+	view->broken = TRUE;
+	for (file = view->log->tail; file != NULL; file = file->next) {
+		if (file->hdr.file_seq > view->max_file_seq)
+			break;
+		if (file->hdr.file_seq >= view->min_file_seq)
+			file->refcount--;
+	}
+
+	mail_transaction_logs_clean(view->log);
+}
+
 void
 mail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
 				       uint32_t *file_seq_r,
@@ -176,6 +177,9 @@
 {
 	va_list va;
 
+	if (!view->broken)
+		mail_transaction_log_view_unset(view);
+
 	view->broken = TRUE;
 
 	va_start(va, fmt);

Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- mail-transaction-log.c	1 May 2004 14:30:37 -0000	1.12
+++ mail-transaction-log.c	1 May 2004 15:32:24 -0000	1.13
@@ -419,8 +419,14 @@
 		return NULL;
 	}
 
-	for (p = &log->tail; *p != NULL; p = &(*p)->next)
-		;
+	for (p = &log->tail; *p != NULL; p = &(*p)->next) {
+		if ((*p)->hdr.file_seq >= file->hdr.file_seq) {
+			/* log replaced with file having same sequence as
+			   previous one. shouldn't happen unless previous
+			   log file was corrupted.. */
+			break;
+		}
+	}
 	*p = file;
 
 	return file;
@@ -461,6 +467,9 @@
 			*p = next;
 		}
 	}
+
+	if (log->tail == NULL)
+		log->head = NULL;
 }
 
 static int mail_transaction_log_rotate(struct mail_transaction_log *log)
@@ -500,6 +509,24 @@
 	return 0;
 }
 
+static int mail_transaction_log_recreate(struct mail_transaction_log *log)
+{
+	unsigned int lock_id;
+	int ret;
+
+	if (mail_index_lock_shared(log->index, TRUE, &lock_id) < 0)
+		return -1;
+
+	ret = mail_transaction_log_rotate(log);
+	mail_index_unlock(log->index, lock_id);
+
+	if (ret == 0) {
+		if (mail_transaction_log_file_lock(log->head, F_UNLCK) < 0)
+			return -1;
+	}
+	return ret;
+}
+
 static int mail_transaction_log_refresh(struct mail_transaction_log *log)
 {
         struct mail_transaction_log_file *file;
@@ -511,6 +538,10 @@
 			   MAIL_TRANSACTION_LOG_PREFIX, NULL);
 	if (stat(path, &st) < 0) {
 		mail_index_file_set_syscall_error(log->index, path, "stat()");
+		if (errno == ENOENT && log->head->lock_type == F_WRLCK) {
+			/* lost? */
+			return mail_transaction_log_recreate(log);
+		}
 		return -1;
 	}
 
@@ -519,6 +550,10 @@
 	    log->head->st_dev == st.st_dev) {
 		/* same file */
 		ret = mail_transaction_log_file_read_hdr(log->head, &st);
+		if (ret == 0 && log->head->lock_type == F_WRLCK) {
+			/* corrupted, recreate */
+			return mail_transaction_log_recreate(log);
+		}
 		return ret <= 0 ? -1 : 0;
 	}
 

Index: mail-transaction-log.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mail-transaction-log.h	1 May 2004 14:30:37 -0000	1.3
+++ mail-transaction-log.h	1 May 2004 15:32:24 -0000	1.4
@@ -67,6 +67,8 @@
 			      uint32_t min_file_seq, uoff_t min_file_offset,
 			      uint32_t max_file_seq, uoff_t max_file_offset,
 			      enum mail_transaction_type type_mask);
+/* Unset view, freeing all it's used resources. */
+void mail_transaction_log_view_unset(struct mail_transaction_log_view *view);
 
 /* Read next transaction record from current position. The position is updated.
    Returns -1 if error, 0 if we're at end of the view, 1 if ok. */



More information about the dovecot-cvs mailing list