changeset 22698:bdb8b4e03f1b

lib-storage: Rebuild list index when doing doveadm force-resync
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 29 Nov 2017 15:14:02 +0200
parents bc0c97a0c7d6
children 324bc758ebf7
files src/lib-storage/list/mailbox-list-index-backend.c src/lib-storage/list/mailbox-list-index.h src/lib-storage/mail-storage-private.h
diffstat 3 files changed, 44 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-index-backend.c	Wed Nov 29 14:51:02 2017 +0200
+++ b/src/lib-storage/list/mailbox-list-index-backend.c	Wed Nov 29 15:14:02 2017 +0200
@@ -573,6 +573,42 @@
 	return 0;
 }
 
+static struct mailbox_sync_context *
+index_list_mailbox_sync_init(struct mailbox *box,
+			     enum mailbox_sync_flags flags)
+{
+	struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
+
+	if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0 &&
+	    !ilist->force_resynced) {
+		box->storage->list_index_rebuild_reason =
+			MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_FORCE_RESYNC;
+		if (box->storage->v.list_index_corrupted(box->storage) < 0)
+			ilist->force_resync_failed = TRUE;
+		/* try to rebuild list index only once - even if it failed */
+		ilist->force_resynced = TRUE;
+	}
+	return ibox->module_ctx.super.sync_init(box, flags);
+}
+
+static int
+index_list_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
+			       struct mailbox_sync_status *status_r)
+{
+	struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(ctx->box);
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(ctx->box->list);
+
+	if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
+		return -1;
+	if (ilist->force_resync_failed) {
+		/* fail this only once */
+		ilist->force_resync_failed = FALSE;
+		return -1;
+	}
+	return 0;
+}
+
 static void
 index_list_try_delete(struct mailbox_list *_list, const char *name,
 		      enum mailbox_list_path_type type)
@@ -855,4 +891,6 @@
 	v->update_box = index_list_mailbox_update;
 	v->exists = index_list_mailbox_exists;
 	v->open = index_list_mailbox_open;
+	v->sync_init = index_list_mailbox_sync_init;
+	v->sync_deinit = index_list_mailbox_sync_deinit;
 }
--- a/src/lib-storage/list/mailbox-list-index.h	Wed Nov 29 14:51:02 2017 +0200
+++ b/src/lib-storage/list/mailbox-list-index.h	Wed Nov 29 15:14:02 2017 +0200
@@ -122,6 +122,8 @@
 	unsigned int handling_corruption:1;
 	unsigned int call_corruption_callback:1;
 	unsigned int rebuild_on_missing_inbox:1;
+	unsigned int force_resynced:1;
+	unsigned int force_resync_failed:1;
 };
 
 struct mailbox_list_index_iterate_context {
--- a/src/lib-storage/mail-storage-private.h	Wed Nov 29 14:51:02 2017 +0200
+++ b/src/lib-storage/mail-storage-private.h	Wed Nov 29 15:14:02 2017 +0200
@@ -29,6 +29,10 @@
 	   this is called in non-error conditions, the callback shouldn't log
 	   any errors or warnings if it didn't find any missing mailboxes. */
 	MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_NO_INBOX,
+	/* MAILBOX_SYNC_FLAG_FORCE_RESYNC is run. This is called only once
+	   per list, so that doveadm force-resync '*' won't cause it to run for
+	   every mailbox. */
+	MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_FORCE_RESYNC,
 };
 
 struct mail_storage_module_register {