From: Timo Sirainen Date: Fri, 10 Apr 2009 18:10:39 +0000 (-0400) Subject: doveadm: Implemented force-resync functionality. X-Git-Tag: 2.0.alpha1~988 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82c70897a2d0e6144ecc56ca8e0eb9fff768f2c5;p=thirdparty%2Fdovecot%2Fcore.git doveadm: Implemented force-resync functionality. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox/dbox-sync.c b/src/lib-storage/index/dbox/dbox-sync.c index 24dbb25f76..fe86c76d06 100644 --- a/src/lib-storage/index/dbox/dbox-sync.c +++ b/src/lib-storage/index/dbox/dbox-sync.c @@ -219,7 +219,8 @@ int dbox_sync_begin(struct dbox_mailbox *mbox, enum dbox_sync_flags flags, int ret; bool rebuild, storage_rebuilt = FALSE; - rebuild = dbox_refresh_header(mbox) < 0; + rebuild = dbox_refresh_header(mbox) < 0 || + (flags & DBOX_SYNC_FLAG_FORCE_REBUILD) != 0; if (rebuild) { if (dbox_storage_rebuild(mbox->storage) < 0) return -1; @@ -322,11 +323,11 @@ int dbox_sync_finish(struct dbox_sync_context **_ctx, bool success) return ret; } -int dbox_sync(struct dbox_mailbox *mbox) +int dbox_sync(struct dbox_mailbox *mbox, enum dbox_sync_flags flags) { struct dbox_sync_context *sync_ctx; - if (dbox_sync_begin(mbox, 0, &sync_ctx) < 0) + if (dbox_sync_begin(mbox, flags, &sync_ctx) < 0) return -1; if (sync_ctx == NULL) @@ -338,14 +339,18 @@ struct mailbox_sync_context * dbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct dbox_mailbox *mbox = (struct dbox_mailbox *)box; + enum dbox_sync_flags dbox_sync_flags = 0; int ret = 0; if (!box->opened) index_storage_mailbox_open(&mbox->ibox); if (index_mailbox_want_full_sync(&mbox->ibox, flags) || - mbox->storage->sync_rebuild) - ret = dbox_sync(mbox); + mbox->storage->sync_rebuild) { + if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0) + dbox_sync_flags |= DBOX_SYNC_FLAG_FORCE_REBUILD; + ret = dbox_sync(mbox, dbox_sync_flags); + } return index_mailbox_sync_init(box, flags, ret < 0); } diff --git a/src/lib-storage/index/dbox/dbox-sync.h b/src/lib-storage/index/dbox/dbox-sync.h index 439e1f770a..90f8c287cc 100644 --- a/src/lib-storage/index/dbox/dbox-sync.h +++ b/src/lib-storage/index/dbox/dbox-sync.h @@ -5,8 +5,9 @@ struct mailbox; struct dbox_mailbox; enum dbox_sync_flags { - DBOX_SYNC_FLAG_FORCE = 0x01, - DBOX_SYNC_FLAG_FSYNC = 0x02 + DBOX_SYNC_FLAG_FORCE = 0x01, + DBOX_SYNC_FLAG_FSYNC = 0x02, + DBOX_SYNC_FLAG_FORCE_REBUILD = 0x04 }; struct dbox_sync_file_entry { @@ -35,7 +36,7 @@ struct dbox_sync_context { int dbox_sync_begin(struct dbox_mailbox *mbox, enum dbox_sync_flags flags, struct dbox_sync_context **ctx_r); int dbox_sync_finish(struct dbox_sync_context **ctx, bool success); -int dbox_sync(struct dbox_mailbox *mbox); +int dbox_sync(struct dbox_mailbox *mbox, enum dbox_sync_flags flags); int dbox_sync_purge(struct mail_storage *storage); int dbox_sync_file(struct dbox_sync_context *ctx, diff --git a/src/lib-storage/index/maildir/maildir-sync.c b/src/lib-storage/index/maildir/maildir-sync.c index e197050d8f..c7ef7ab088 100644 --- a/src/lib-storage/index/maildir/maildir-sync.c +++ b/src/lib-storage/index/maildir/maildir-sync.c @@ -893,16 +893,17 @@ maildir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct maildir_mailbox *mbox = (struct maildir_mailbox *)box; struct maildir_sync_context *ctx; - bool lost_files; + bool lost_files, force_resync; int ret = 0; if (!box->opened) index_storage_mailbox_open(&mbox->ibox); + force_resync = (flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0; if (index_mailbox_want_full_sync(&mbox->ibox, flags)) { T_BEGIN { ctx = maildir_sync_context_new(mbox, flags); - ret = maildir_sync_context(ctx, FALSE, NULL, + ret = maildir_sync_context(ctx, force_resync, NULL, &lost_files); maildir_sync_deinit(ctx); } T_END; diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 64c4acafcf..ec123f57bf 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -1929,6 +1929,11 @@ mbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) mbox_sync_flags |= MBOX_SYNC_UNDIRTY; if ((flags & MAILBOX_SYNC_FLAG_FULL_WRITE) != 0) mbox_sync_flags |= MBOX_SYNC_REWRITE; + if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0) { + mbox_sync_flags |= MBOX_SYNC_UNDIRTY | + MBOX_SYNC_REWRITE | MBOX_SYNC_FORCE_SYNC; + } + ret = mbox_sync(mbox, mbox_sync_flags); } diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 866f405c32..86ed2c4174 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -346,7 +346,8 @@ const char *mail_storage_get_last_error(struct mail_storage *storage, error. If storage->error is NONE, it means we forgot to set it at some point.. */ if (storage->error == MAIL_ERROR_NONE) { - *error_r = MAIL_ERROR_TEMP; + if (error_r != NULL) + *error_r = MAIL_ERROR_TEMP; return storage->error_string != NULL ? storage->error_string : "BUG: Unknown internal error"; } @@ -358,7 +359,8 @@ const char *mail_storage_get_last_error(struct mail_storage *storage, storage->error); } - *error_r = storage->error; + if (error_r != NULL) + *error_r = storage->error; return storage->error_string; } diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index af1b82b929..06b662d22c 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -151,7 +151,9 @@ enum mailbox_sync_flags { MAILBOX_SYNC_FLAG_FIX_INCONSISTENT = 0x40, /* Syncing after an EXPUNGE command. This is just an informational flag for plugins. */ - MAILBOX_SYNC_FLAG_EXPUNGE = 0x80 + MAILBOX_SYNC_FLAG_EXPUNGE = 0x80, + /* Force doing a full resync of indexes. */ + MAILBOX_SYNC_FLAG_FORCE_RESYNC = 0x100 }; enum mailbox_sync_type { diff --git a/src/util/doveadm.c b/src/util/doveadm.c index f0d6bb10e3..1ce8a37ac7 100644 --- a/src/util/doveadm.c +++ b/src/util/doveadm.c @@ -16,21 +16,66 @@ static struct mail_user *mail_user; static void ATTR_NORETURN usage(void) { - i_fatal("usage: doveadm purge \n"); + i_fatal( +"usage: doveadm \n" +" purge \n" +" force-resync \n" +); } -static int cmd_purge(struct mail_user *user) +static void cmd_purge(struct mail_user *user) { struct mail_namespace *ns; - int ret = 0; for (ns = user->namespaces; ns != NULL; ns = ns->next) { - if (ns->type == NAMESPACE_PRIVATE && ns->alias_for == NULL) { - if (mail_storage_purge(ns->storage) < 0) - ret = -1; + if (ns->type != NAMESPACE_PRIVATE || ns->alias_for != NULL) + continue; + + if (mail_storage_purge(ns->storage) < 0) { + i_error("Purging namespace '%s' failed: %s", ns->prefix, + mail_storage_get_last_error(ns->storage, NULL)); } } - return ret; +} + +static struct mailbox * +mailbox_find_and_open(struct mail_user *user, const char *mailbox) +{ + struct mail_namespace *ns; + struct mail_storage *storage; + struct mailbox *box; + const char *orig_mailbox = mailbox; + + ns = mail_namespace_find(user->namespaces, &mailbox); + if (ns == NULL) + i_fatal("Can't find namespace for mailbox %s", mailbox); + + storage = ns->storage; + box = mailbox_open(&storage, mailbox, NULL, MAILBOX_OPEN_KEEP_RECENT | + MAILBOX_OPEN_IGNORE_ACLS); + if (box == NULL) { + i_fatal("Opening mailbox %s failed: %s", orig_mailbox, + mail_storage_get_last_error(storage, NULL)); + } + return box; +} + +static void cmd_force_resync(struct mail_user *user, const char *mailbox) +{ + struct mail_storage *storage; + struct mailbox *box; + + if (mailbox == NULL) + usage(); + + box = mailbox_find_and_open(user, mailbox); + storage = mailbox_get_storage(box); + if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC | + MAILBOX_SYNC_FLAG_FIX_INCONSISTENT, 0, NULL) < 0) { + i_fatal("Forcing a resync on mailbox %s failed: %s", mailbox, + mail_storage_get_last_error(storage, NULL)); + } + mailbox_close(&box); } int main(int argc, char *argv[]) @@ -38,7 +83,7 @@ int main(int argc, char *argv[]) enum mail_storage_service_flags service_flags = 0; struct master_service *service; const char *getopt_str, *user; - int c, ret = 0; + int c; service = master_service_init("doveadm", MASTER_SERVICE_FLAG_STANDALONE, argc, argv); @@ -71,12 +116,14 @@ int main(int argc, char *argv[]) mail_user->username)); if (strcmp(argv[optind], "purge") == 0) - ret = cmd_purge(mail_user); + cmd_purge(mail_user); + else if (strcmp(argv[optind], "force-resync") == 0) + cmd_force_resync(mail_user, argv[optind+2]); else usage(); mail_user_unref(&mail_user); mail_storage_service_deinit_user(); master_service_deinit(&service); - return ret < 0 ? 1 : 0; + return 0; }