dovecot-2.2: dsync: Use storage's mail_error to choose the dovea...

dovecot at dovecot.org dovecot at dovecot.org
Wed Mar 18 23:25:27 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/b900b50085fc
changeset: 18371:b900b50085fc
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 19 00:41:19 2015 +0200
description:
dsync: Use storage's mail_error to choose the doveadm exit code.
Instead of always assuming that all errors are EX_TEMPFAIL.

diffstat:

 src/doveadm/doveadm-dsync.c                       |  28 ++++++---
 src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c |  24 +++++---
 src/doveadm/dsync/dsync-brain-mailbox-tree.c      |  10 ++-
 src/doveadm/dsync/dsync-brain-mailbox.c           |  57 ++++++++++++--------
 src/doveadm/dsync/dsync-brain-mails.c             |  11 ++-
 src/doveadm/dsync/dsync-brain-private.h           |   8 ++-
 src/doveadm/dsync/dsync-brain.c                   |  16 ++++-
 src/doveadm/dsync/dsync-brain.h                   |   3 +-
 src/doveadm/dsync/dsync-ibc-pipe.c                |  17 ++++-
 src/doveadm/dsync/dsync-ibc-private.h             |   6 +-
 src/doveadm/dsync/dsync-ibc-stream.c              |  21 ++++++-
 src/doveadm/dsync/dsync-ibc.c                     |  10 ++-
 src/doveadm/dsync/dsync-ibc.h                     |   7 +-
 src/doveadm/dsync/dsync-mailbox-export.c          |  30 +++++++--
 src/doveadm/dsync/dsync-mailbox-export.h          |   2 +-
 src/doveadm/dsync/dsync-mailbox-import.c          |  64 ++++++++++++++++------
 src/doveadm/dsync/dsync-mailbox-import.h          |   5 +-
 src/doveadm/dsync/dsync-mailbox-tree-fill.c       |  34 +++++++----
 src/doveadm/dsync/dsync-mailbox-tree.h            |   4 +-
 19 files changed, 245 insertions(+), 112 deletions(-)

diffs (truncated from 1291 to 300 lines):

diff -r b28de884c470 -r b900b50085fc src/doveadm/doveadm-dsync.c
--- a/src/doveadm/doveadm-dsync.c	Thu Mar 19 00:38:01 2015 +0200
+++ b/src/doveadm/doveadm-dsync.c	Thu Mar 19 00:41:19 2015 +0200
@@ -322,7 +322,7 @@
 static int
 cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user,
 		    struct dsync_brain *brain, struct dsync_ibc *ibc2,
-		    bool *changes_during_sync_r)
+		    bool *changes_during_sync_r, enum mail_error *mail_error_r)
 {
 	struct dsync_brain *brain2;
 	struct mail_user *user2;
@@ -331,6 +331,8 @@
 	bool brain1_running, brain2_running, changed1, changed2;
 	int ret;
 
+	*mail_error_r = 0;
+
 	if (ctx->local_location_from_arg)
 		location = ctx->ctx.args[0];
 	else {
@@ -389,11 +391,7 @@
 		brain2_running = dsync_brain_run(brain2, &changed2);
 	}
 	*changes_during_sync_r = dsync_brain_has_unexpected_changes(brain2);
-	if (dsync_brain_deinit(&brain2) < 0) {
-		ctx->ctx.exit_code = EX_TEMPFAIL;
-		return -1;
-	}
-	return 0;
+	return dsync_brain_deinit(&brain2, mail_error_r);
 }
 
 static void cmd_dsync_wait_remote(struct dsync_cmd_context *ctx,
@@ -534,6 +532,7 @@
 	struct mail_namespace *ns;
 	const char *const *strp;
 	enum dsync_brain_flags brain_flags;
+	enum mail_error mail_error = 0, mail_error2;
 	bool remote_errors_logged = FALSE;
 	bool changes_during_sync = FALSE;
 	int status = 0, ret = 0;
@@ -605,7 +604,7 @@
 
 	if (ctx->run_type == DSYNC_RUN_TYPE_LOCAL) {
 		if (cmd_dsync_run_local(ctx, user, brain, ibc2,
-					&changes_during_sync) < 0)
+					&changes_during_sync, &mail_error) < 0)
 			ret = -1;
 	} else {
 		cmd_dsync_run_remote(user);
@@ -626,9 +625,15 @@
 		}
 		ctx->ctx.exit_code = 2;
 	}
-	if (dsync_brain_deinit(&brain) < 0) {
-		ctx->ctx.exit_code = EX_TEMPFAIL;
+	if (dsync_brain_deinit(&brain, &mail_error2) < 0)
 		ret = -1;
+	if (ret < 0) {
+		/* tempfail is the default error. prefer to use a non-tempfail
+		   if that exists. */
+		if (mail_error2 != 0 &&
+		    (mail_error == 0 || mail_error == MAIL_ERROR_TEMP))
+			mail_error = mail_error2;
+		doveadm_mail_failed_error(&ctx->ctx, mail_error);
 	}
 	dsync_ibc_deinit(&ibc);
 	if (ibc2 != NULL)
@@ -1039,6 +1044,7 @@
 	string_t *temp_prefix, *state_str = NULL;
 	enum dsync_brain_sync_type sync_type;
 	const char *name, *process_title_prefix = "";
+	enum mail_error mail_error;
 
 	if (_ctx->conn != NULL) {
 		/* doveadm-server connection. start with a success reply.
@@ -1078,8 +1084,8 @@
 	}
 	sync_type = dsync_brain_get_sync_type(brain);
 
-	if (dsync_brain_deinit(&brain) < 0)
-		_ctx->exit_code = EX_TEMPFAIL;
+	if (dsync_brain_deinit(&brain, &mail_error) < 0)
+		doveadm_mail_failed_error(_ctx, mail_error);
 	dsync_ibc_deinit(&ibc);
 
 	if (_ctx->conn != NULL) {
diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c	Thu Mar 19 00:38:01 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c	Thu Mar 19 00:41:19 2015 +0200
@@ -8,7 +8,8 @@
 
 static int
 sync_create_box(struct dsync_brain *brain, struct mailbox *box,
-		const guid_128_t mailbox_guid, uint32_t uid_validity)
+		const guid_128_t mailbox_guid, uint32_t uid_validity,
+		enum mail_error *error_r)
 {
 	struct mailbox_metadata metadata;
 	struct mailbox_update update;
@@ -25,6 +26,7 @@
 		if (error != MAIL_ERROR_EXISTS) {
 			i_error("Can't create mailbox %s: %s",
 				mailbox_get_vname(box), errstr);
+			*error_r = error;
 			return -1;
 		}
 	}
@@ -37,7 +39,7 @@
 	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
 		i_error("Can't sync mailbox %s: %s",
 			mailbox_get_vname(box),
-			mailbox_get_last_error(box, NULL));
+			mailbox_get_last_error(box, error_r));
 		return -1;
 	}
 
@@ -50,7 +52,7 @@
 	if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
 		i_error("Can't get mailbox GUID %s: %s",
 			mailbox_get_vname(box),
-			mailbox_get_last_error(box, NULL));
+			mailbox_get_last_error(box, error_r));
 		return -1;
 	}
 
@@ -69,7 +71,7 @@
 		if (mailbox_update(box, &update) < 0) {
 			i_error("Can't update mailbox GUID %s: %s",
 				mailbox_get_vname(box),
-				mailbox_get_last_error(box, NULL));
+				mailbox_get_last_error(box, error_r));
 			return -1;
 		}
 		/* verify that the update worked */
@@ -77,13 +79,14 @@
 					 &metadata) < 0) {
 			i_error("Can't get mailbox GUID %s: %s",
 				mailbox_get_vname(box),
-				mailbox_get_last_error(box, NULL));
+				mailbox_get_last_error(box, error_r));
 			return -1;
 		}
 		if (memcmp(mailbox_guid, metadata.guid,
 			   sizeof(metadata.guid)) != 0) {
 			i_error("Backend didn't update mailbox %s GUID",
 				mailbox_get_vname(box));
+			*error_r = MAIL_ERROR_TEMP;
 			return -1;
 		}
 	} else if (ret < 0) {
@@ -100,7 +103,8 @@
 }
 
 int dsync_brain_mailbox_tree_sync_change(struct dsync_brain *brain,
-			const struct dsync_mailbox_tree_sync_change *change)
+			const struct dsync_mailbox_tree_sync_change *change,
+			enum mail_error *error_r)
 {
 	struct mailbox *box = NULL, *destbox;
 	const char *errstr, *func_name = NULL, *storage_name;
@@ -116,7 +120,7 @@
 	case DSYNC_MAILBOX_TREE_SYNC_TYPE_DELETE_BOX:
 		/* make sure we're deleting the correct mailbox */
 		ret = dsync_brain_mailbox_alloc(brain, change->mailbox_guid,
-						&box, &errstr);
+						&box, &errstr, error_r);
 		if (ret < 0) {
 			i_error("Mailbox sync: Couldn't allocate mailbox GUID %s: %s",
 				guid_128_to_string(change->mailbox_guid), errstr);
@@ -130,7 +134,7 @@
 					guid_128_to_string(change->mailbox_guid), errstr);
 			}
 			brain->changes_during_sync = TRUE;
-			return ret;
+			return 0;
 		}
 		break;
 	case DSYNC_MAILBOX_TREE_SYNC_TYPE_DELETE_DIR:
@@ -153,6 +157,7 @@
 		} else {
 			i_error("Mailbox sync: mailbox_list_delete_dir failed: %s",
 				errstr);
+			*error_r = error;
 			return -1;
 		}
 	default:
@@ -162,7 +167,7 @@
 	switch (change->type) {
 	case DSYNC_MAILBOX_TREE_SYNC_TYPE_CREATE_BOX:
 		ret = sync_create_box(brain, box, change->mailbox_guid,
-				      change->uid_validity);
+				      change->uid_validity, error_r);
 		mailbox_free(&box);
 		return ret;
 	case DSYNC_MAILBOX_TREE_SYNC_TYPE_CREATE_DIR:
@@ -218,6 +223,7 @@
 		} else {
 			i_error("Mailbox %s sync: %s failed: %s",
 				mailbox_get_vname(box), func_name, errstr);
+			*error_r = error;
 		}
 	}
 	mailbox_free(&box);
diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox-tree.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Thu Mar 19 00:38:01 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Thu Mar 19 00:41:19 2015 +0200
@@ -58,8 +58,11 @@
 		if (dsync_mailbox_tree_fill(brain->local_mailbox_tree, ns,
 					    brain->sync_box,
 					    brain->sync_box_guid,
-					    brain->exclude_mailboxes) < 0)
+					    brain->exclude_mailboxes,
+					    &brain->mail_error) < 0) {
 			brain->failed = TRUE;
+			break;
+		}
 	}
 
 	brain->local_tree_iter =
@@ -300,8 +303,11 @@
 					    brain->remote_mailbox_tree,
 					    sync_type, sync_flags);
 	while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) {
-		if (dsync_brain_mailbox_tree_sync_change(brain, change) < 0)
+		if (dsync_brain_mailbox_tree_sync_change(brain, change,
+							 &brain->mail_error) < 0) {
 			brain->failed = TRUE;
+			break;
+		}
 	}
 	dsync_mailbox_trees_sync_deinit(&ctx);
 }
diff -r b28de884c470 -r b900b50085fc src/doveadm/dsync/dsync-brain-mailbox.c
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Thu Mar 19 00:38:01 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Thu Mar 19 00:41:19 2015 +0200
@@ -16,12 +16,11 @@
 static int
 ns_mailbox_try_alloc(struct dsync_brain *brain, struct mail_namespace *ns,
 		     const guid_128_t guid, struct mailbox **box_r,
-		     const char **error_r)
+		     const char **errstr_r, enum mail_error *error_r)
 {
 	enum mailbox_flags flags = 0;
 	struct mailbox *box;
 	enum mailbox_existence existence;
-	enum mail_error err;
 	int ret;
 
 	if (brain->backup_send) {
@@ -32,13 +31,13 @@
 	box = mailbox_alloc_guid(ns->list, guid, flags);
 	ret = mailbox_exists(box, FALSE, &existence);
 	if (ret < 0) {
-		*error_r = mailbox_get_last_error(box, &err);
+		*errstr_r = mailbox_get_last_error(box, error_r);
 		mailbox_free(&box);
 		return -1;
 	}
 	if (existence != MAILBOX_EXISTENCE_SELECT) {
 		mailbox_free(&box);
-		*error_r = existence == MAILBOX_EXISTENCE_NONE ?
+		*errstr_r = existence == MAILBOX_EXISTENCE_NONE ?
 			"Mailbox was already deleted" :
 			"Mailbox is no longer selectable";
 		return 0;
@@ -48,7 +47,8 @@
 }
 
 int dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid,
-			      struct mailbox **box_r, const char **error_r)
+			      struct mailbox **box_r, const char **errstr_r,
+			      enum mail_error *error_r)
 {
 	struct mail_namespace *ns;
 	int ret;
@@ -58,11 +58,9 @@
 	for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
 		if (!dsync_brain_want_namespace(brain, ns))
 			continue;
-		if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r, error_r)) != 0) {
-			if (ret < 0)
-				brain->failed = TRUE;
+		if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r,
+						errstr_r, error_r)) != 0)
 			return ret;
-		}
 	}
 	return 0;
 }
@@ -329,6 +327,8 @@
 
 void dsync_brain_sync_mailbox_deinit(struct dsync_brain *brain)
 {
+	enum mail_error error;
+
 	i_assert(brain->box != NULL);
 
 	if (brain->require_full_resync) {


More information about the dovecot-cvs mailing list