]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Rebuild list index when doing doveadm force-resync
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Nov 2017 13:14:02 +0000 (15:14 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Nov 2017 13:42:18 +0000 (15:42 +0200)
src/lib-storage/list/mailbox-list-index-backend.c
src/lib-storage/list/mailbox-list-index.h
src/lib-storage/mail-storage-private.h

index 5fe8a3837fa0e6eae5074391b07ad31318bee36f..3ffad2ed402dbbf32c180fac7d35787d3f577427 100644 (file)
@@ -573,6 +573,42 @@ static int index_list_mailbox_open(struct mailbox *box)
        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 @@ void mailbox_list_index_backend_init_mailbox(struct mailbox *box,
        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;
 }
index e6d5de18b2184a5608f0b242b602e7d3e1a95a30..9dc1c486c22d3d1fae06b3c0508e5cf5cecb3792 100644 (file)
@@ -122,6 +122,8 @@ struct mailbox_list_index {
        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 {
index 4a9b790bd1495e0093cb8f8194f73de391063c33..822294ec250eaf761c8f9691118c1fe69e245450 100644 (file)
@@ -29,6 +29,10 @@ enum mail_storage_list_index_rebuild_reason {
           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 {