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