From: Timo Sirainen Date: Thu, 27 Aug 2015 11:38:44 +0000 (+0200) Subject: dsync: Added -D parameter to disable mailbox renaming. X-Git-Tag: 2.2.19.rc1~173 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1a1d00fd04bfcf8436b00b58d527e46b23523c9d;p=thirdparty%2Fdovecot%2Fcore.git dsync: Added -D parameter to disable mailbox renaming. The renaming logic is annoyingly complex and there are some bugs left in it. With this parameter renames are never even attempted, but instead a rename would be done (slowly) with mailbox delete + create + fill. Although with imapc protocol mailbox renames are rarely detected anyway. --- diff --git a/src/doveadm/doveadm-dsync.c b/src/doveadm/doveadm-dsync.c index afb5e788f7..053d60b5fb 100644 --- a/src/doveadm/doveadm-dsync.c +++ b/src/doveadm/doveadm-dsync.c @@ -39,7 +39,7 @@ #include #include -#define DSYNC_COMMON_GETOPT_ARGS "+1a:dEfg:l:m:n:NO:Pr:Rs:t:T:Ux:" +#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:l:m:n:NO:Pr:Rs:t:T:Ux:" #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30 /* The broken_char is mainly set to get a proper error message when trying to convert a mailbox with a name that can't be used properly translated between @@ -100,6 +100,7 @@ struct dsync_cmd_context { unsigned int reverse_backup:1; unsigned int remote_user_prefix:1; unsigned int no_mail_sync:1; + unsigned int no_mailbox_renames:1; unsigned int local_location_from_arg:1; unsigned int replicator_notify:1; unsigned int exited:1; @@ -606,6 +607,8 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) brain_flags |= DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES; if (ctx->purge_remote) brain_flags |= DSYNC_BRAIN_FLAG_PURGE_REMOTE; + if (ctx->no_mailbox_renames) + brain_flags |= DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES; if (ctx->reverse_backup) brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV; @@ -952,6 +955,9 @@ cmd_mailbox_dsync_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) case 'd': ctx->default_replica_location = TRUE; break; + case 'D': + ctx->no_mailbox_renames = TRUE; + break; case 'E': /* dsync wrapper detection flag */ legacy_dsync = TRUE; diff --git a/src/doveadm/dsync/dsync-brain-mailbox-tree.c b/src/doveadm/dsync/dsync-brain-mailbox-tree.c index 1950a39fd6..26a94bacb6 100644 --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c @@ -288,7 +288,8 @@ static void dsync_brain_mailbox_trees_sync(struct dsync_brain *brain) enum dsync_mailbox_trees_sync_type sync_type; enum dsync_mailbox_trees_sync_flags sync_flags = (brain->debug ? DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG : 0) | - (brain->master_brain ? DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN : 0); + (brain->master_brain ? DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN : 0) | + (brain->no_mailbox_renames ? DSYNC_MAILBOX_TREES_SYNC_FLAG_NO_RENAMES : 0); if (brain->no_backup_overwrite) sync_type = DSYNC_MAILBOX_TREES_SYNC_TYPE_TWOWAY; diff --git a/src/doveadm/dsync/dsync-brain-private.h b/src/doveadm/dsync/dsync-brain-private.h index 22fdfa0196..391df6142c 100644 --- a/src/doveadm/dsync/dsync-brain-private.h +++ b/src/doveadm/dsync/dsync-brain-private.h @@ -107,6 +107,7 @@ struct dsync_brain { unsigned int no_mail_sync:1; unsigned int no_backup_overwrite:1; unsigned int no_mail_prefetch:1; + unsigned int no_mailbox_renames:1; unsigned int changes_during_sync:1; unsigned int require_full_resync:1; unsigned int verbose_proctitle:1; diff --git a/src/doveadm/dsync/dsync-brain.c b/src/doveadm/dsync/dsync-brain.c index 8d3e7b0e9f..0c91dd850e 100644 --- a/src/doveadm/dsync/dsync-brain.c +++ b/src/doveadm/dsync/dsync-brain.c @@ -140,6 +140,8 @@ dsync_brain_set_flags(struct dsync_brain *brain, enum dsync_brain_flags flags) (flags & DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE) != 0; brain->no_mail_prefetch = (flags & DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH) != 0; + brain->no_mailbox_renames = + (flags & DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES) != 0; } static void diff --git a/src/doveadm/dsync/dsync-brain.h b/src/doveadm/dsync/dsync-brain.h index aff373b104..0a8962c39f 100644 --- a/src/doveadm/dsync/dsync-brain.h +++ b/src/doveadm/dsync/dsync-brain.h @@ -27,7 +27,10 @@ enum dsync_brain_flags { /* Don't prefetch mail bodies until they're actually needed. This works only with pipe ibc. It's useful if most of the mails can be copied directly within filesystem without having to read them. */ - DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH = 0x100 + DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH = 0x100, + /* Disable mailbox renaming logic. This is just a kludge that should + be removed once the renaming logic has no more bugs.. */ + DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES = 0x200 }; enum dsync_brain_sync_type { diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index 656a06feb9..1a9f35f2b2 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -76,7 +76,7 @@ static const struct { .optional_keys = "sync_ns_prefix sync_box sync_box_guid sync_type " "debug sync_visible_namespaces exclude_mailboxes " "send_mail_requests backup_send backup_recv lock_timeout " - "no_mail_sync no_backup_overwrite purge_remote " + "no_mail_sync no_mailbox_renames no_backup_overwrite purge_remote " "sync_since_timestamp sync_flags virtual_all_box" }, { .name = "mailbox_state", @@ -681,6 +681,8 @@ dsync_ibc_stream_send_handshake(struct dsync_ibc *_ibc, dsync_serializer_encode_add(encoder, "sync_visible_namespaces", ""); if ((set->brain_flags & DSYNC_BRAIN_FLAG_NO_MAIL_SYNC) != 0) dsync_serializer_encode_add(encoder, "no_mail_sync", ""); + if ((set->brain_flags & DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES) != 0) + dsync_serializer_encode_add(encoder, "no_mailbox_renames", ""); if ((set->brain_flags & DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE) != 0) dsync_serializer_encode_add(encoder, "no_backup_overwrite", ""); if ((set->brain_flags & DSYNC_BRAIN_FLAG_PURGE_REMOTE) != 0) @@ -785,6 +787,8 @@ dsync_ibc_stream_recv_handshake(struct dsync_ibc *_ibc, set->brain_flags |= DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES; if (dsync_deserializer_decode_try(decoder, "no_mail_sync", &value)) set->brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; + if (dsync_deserializer_decode_try(decoder, "no_mailbox_renames", &value)) + set->brain_flags |= DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES; if (dsync_deserializer_decode_try(decoder, "no_backup_overwrite", &value)) set->brain_flags |= DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE; if (dsync_deserializer_decode_try(decoder, "purge_remote", &value)) diff --git a/src/doveadm/dsync/dsync-mailbox-tree-sync.c b/src/doveadm/dsync/dsync-mailbox-tree-sync.c index 20b49bc4c8..9bc0390eab 100644 --- a/src/doveadm/dsync/dsync-mailbox-tree-sync.c +++ b/src/doveadm/dsync/dsync-mailbox-tree-sync.c @@ -1071,6 +1071,26 @@ sync_rename_temp_mailboxes(struct dsync_mailbox_tree_sync_ctx *ctx, return FALSE; } +static void +dsync_mailbox_tree_handle_renames(struct dsync_mailbox_tree_sync_ctx *ctx) +{ + bool changed; + + do { + T_BEGIN { + changed = sync_rename_mailboxes(ctx, &ctx->local_tree->root, + &ctx->remote_tree->root); + } T_END; + if ((ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG) != 0 && + changed) { + i_debug("brain %c: -- Mailbox renamed, restart sync --", + (ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN) != 0 ? 'M' : 'S'); + } + } while (changed); + while (sync_rename_temp_mailboxes(ctx, ctx->local_tree, &ctx->local_tree->root)) ; + while (sync_rename_temp_mailboxes(ctx, ctx->remote_tree, &ctx->remote_tree->root)) ; +} + static bool sync_is_wrong_mailbox(struct dsync_mailbox_node *node, const struct dsync_mailbox_node *wanted_node, const char **reason_r) @@ -1348,7 +1368,6 @@ dsync_mailbox_trees_sync_init(struct dsync_mailbox_tree *local_tree, { struct dsync_mailbox_tree_sync_ctx *ctx; pool_t pool; - bool changed; i_assert(hash_table_is_created(local_tree->guid_hash)); i_assert(hash_table_is_created(remote_tree->guid_hash)); @@ -1370,19 +1389,8 @@ dsync_mailbox_trees_sync_init(struct dsync_mailbox_tree *local_tree, dsync_mailbox_tree_update_child_timestamps(&local_tree->root, 0); dsync_mailbox_tree_update_child_timestamps(&remote_tree->root, 0); - do { - T_BEGIN { - changed = sync_rename_mailboxes(ctx, &local_tree->root, - &remote_tree->root); - } T_END; - if ((ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG) != 0 && - changed) { - i_debug("brain %c: -- Mailbox renamed, restart sync --", - (ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN) != 0 ? 'M' : 'S'); - } - } while (changed); - while (sync_rename_temp_mailboxes(ctx, local_tree, &local_tree->root)) ; - while (sync_rename_temp_mailboxes(ctx, remote_tree, &remote_tree->root)) ; + if ((sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_NO_RENAMES) == 0) + dsync_mailbox_tree_handle_renames(ctx); /* if we're not doing a two-way sync, delete now any mailboxes, which a) shouldn't exist, b) doesn't have a matching GUID/UIDVALIDITY, diff --git a/src/doveadm/dsync/dsync-mailbox-tree.h b/src/doveadm/dsync/dsync-mailbox-tree.h index 7292afdfb4..e7558e9926 100644 --- a/src/doveadm/dsync/dsync-mailbox-tree.h +++ b/src/doveadm/dsync/dsync-mailbox-tree.h @@ -20,7 +20,10 @@ enum dsync_mailbox_trees_sync_flags { /* Enable debugging */ DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG = 0x01, /* Show ourself as "master brain" in the debug output */ - DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN = 0x02 + DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN = 0x02, + /* Disable mailbox renaming logic. This is just a kludge that should + be removed once the renaming logic has no more bugs.. */ + DSYNC_MAILBOX_TREES_SYNC_FLAG_NO_RENAMES = 0x04 }; enum dsync_mailbox_node_existence {