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.
#include <ctype.h>
#include <sys/wait.h>
-#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
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;
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;
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;
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;
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;
(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
/* 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 {
.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",
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)
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))
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)
{
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));
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,
/* 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 {