dovecot-1.3: doveadm: Implemented force-resync functionality.

dovecot at dovecot.org dovecot at dovecot.org
Fri Apr 10 21:10:46 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.3/rev/d8e8a9c447af
changeset: 9064:d8e8a9c447af
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Apr 10 14:10:39 2009 -0400
description:
doveadm: Implemented force-resync functionality.

diffstat:

7 files changed, 86 insertions(+), 23 deletions(-)
src/lib-storage/index/dbox/dbox-sync.c       |   15 +++--
src/lib-storage/index/dbox/dbox-sync.h       |    7 +-
src/lib-storage/index/maildir/maildir-sync.c |    5 +
src/lib-storage/index/mbox/mbox-sync.c       |    5 +
src/lib-storage/mail-storage.c               |    6 +-
src/lib-storage/mail-storage.h               |    4 +
src/util/doveadm.c                           |   67 ++++++++++++++++++++++----

diffs (250 lines):

diff -r daa079a90b66 -r d8e8a9c447af src/lib-storage/index/dbox/dbox-sync.c
--- a/src/lib-storage/index/dbox/dbox-sync.c	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-sync.c	Fri Apr 10 14:10:39 2009 -0400
@@ -219,7 +219,8 @@ int dbox_sync_begin(struct dbox_mailbox 
 	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_co
 	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 @@ dbox_storage_sync_init(struct mailbox *b
 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 -r daa079a90b66 -r d8e8a9c447af src/lib-storage/index/dbox/dbox-sync.h
--- a/src/lib-storage/index/dbox/dbox-sync.h	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-sync.h	Fri Apr 10 14:10:39 2009 -0400
@@ -5,8 +5,9 @@ struct dbox_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 @@ int dbox_sync_begin(struct dbox_mailbox 
 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 -r daa079a90b66 -r d8e8a9c447af src/lib-storage/index/maildir/maildir-sync.c
--- a/src/lib-storage/index/maildir/maildir-sync.c	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Fri Apr 10 14:10:39 2009 -0400
@@ -893,16 +893,17 @@ maildir_storage_sync_init(struct mailbox
 {
 	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 -r daa079a90b66 -r d8e8a9c447af src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Fri Apr 10 14:10:39 2009 -0400
@@ -1929,6 +1929,11 @@ mbox_storage_sync_init(struct mailbox *b
 			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 -r daa079a90b66 -r d8e8a9c447af src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/mail-storage.c	Fri Apr 10 14:10:39 2009 -0400
@@ -346,7 +346,8 @@ const char *mail_storage_get_last_error(
 	   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(
 					storage->error);
 	}
 
-	*error_r = storage->error;
+	if (error_r != NULL)
+		*error_r = storage->error;
 	return storage->error_string;
 }
 
diff -r daa079a90b66 -r d8e8a9c447af src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/lib-storage/mail-storage.h	Fri Apr 10 14:10:39 2009 -0400
@@ -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 -r daa079a90b66 -r d8e8a9c447af src/util/doveadm.c
--- a/src/util/doveadm.c	Fri Apr 10 13:38:43 2009 -0400
+++ b/src/util/doveadm.c	Fri Apr 10 14:10:39 2009 -0400
@@ -16,21 +16,66 @@ static void ATTR_NORETURN
 static void ATTR_NORETURN
 usage(void)
 {
-	i_fatal("usage: doveadm purge <user>\n");
+	i_fatal(
+"usage: doveadm \n"
+"  purge <user>\n"
+"  force-resync <user> <mailbox>\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;
 }


More information about the dovecot-cvs mailing list