From: Timo Sirainen Date: Wed, 6 May 2015 13:16:11 +0000 (+0300) Subject: dsync: Don't try to rename namespace roots. X-Git-Tag: 2.2.17.rc1~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d12ea923bd1d532c6f7fee44304dde8d0f321dd0;p=thirdparty%2Fdovecot%2Fcore.git dsync: Don't try to rename namespace roots. It'll just cause an assert-crash. --- diff --git a/src/doveadm/dsync/dsync-mailbox-tree-sync.c b/src/doveadm/dsync/dsync-mailbox-tree-sync.c index c4b83caf40..f0a149e8df 100644 --- a/src/doveadm/dsync/dsync-mailbox-tree-sync.c +++ b/src/doveadm/dsync/dsync-mailbox-tree-sync.c @@ -363,6 +363,9 @@ static bool sync_node_is_namespace_prefix(struct dsync_mailbox_tree *tree, const char *full_name; unsigned int prefix_len = node->ns == NULL ? 0 : node->ns->prefix_len; + if (strcmp(node->name, "INBOX") == 0 && node->parent == &tree->root) + return TRUE; + if (prefix_len == 0) return FALSE; @@ -585,6 +588,16 @@ static time_t nodes_get_timestamp(struct dsync_mailbox_node *node1, return ts; } +static bool sync_node_is_namespace_root(struct dsync_mailbox_tree *tree, + struct dsync_mailbox_node *node) +{ + if (node == NULL) + return FALSE; + if (node == &tree->root) + return TRUE; + return sync_node_is_namespace_prefix(tree, node); +} + static bool ATTR_NULL(3, 4) sync_rename_lower_ts(struct dsync_mailbox_tree_sync_ctx *ctx, struct dsync_mailbox_node *local_node1, @@ -604,6 +617,16 @@ sync_rename_lower_ts(struct dsync_mailbox_tree_sync_ctx *ctx, at all. Note that node1 and node2 may be the same node pointers. */ i_assert(strcmp(local_node1->name, remote_node2->name) == 0); + if (sync_node_is_namespace_root(ctx->remote_tree, remote_node1) || + sync_node_is_namespace_root(ctx->remote_tree, remote_node2) || + sync_node_is_namespace_root(ctx->local_tree, local_node1) || + sync_node_is_namespace_root(ctx->local_tree, local_node2)) { + local_node1->sync_delayed_guid_change = TRUE; + remote_node2->sync_delayed_guid_change = TRUE; + *reason_r = "Can't rename namespace prefixes - will be merged later"; + return FALSE; + } + local_ts = nodes_get_timestamp(local_node1, local_node2); remote_ts = nodes_get_timestamp(remote_node1, remote_node2); @@ -791,14 +814,6 @@ sync_find_branch(struct dsync_mailbox_tree *tree, return NULL; } -static bool sync_node_is_namespace_root(struct dsync_mailbox_tree *tree, - struct dsync_mailbox_node *node) -{ - if (node == &tree->root) - return TRUE; - return sync_node_is_namespace_prefix(tree, node); -} - static bool sync_rename_directory(struct dsync_mailbox_tree_sync_ctx *ctx, struct dsync_mailbox_node *local_node1, struct dsync_mailbox_node *remote_node2, @@ -821,13 +836,6 @@ static bool sync_rename_directory(struct dsync_mailbox_tree_sync_ctx *ctx, *reason_r = "Directory name paths are equal"; return FALSE; } - if (sync_node_is_namespace_root(ctx->remote_tree, remote_node1) || - sync_node_is_namespace_root(ctx->remote_tree, remote_node2) || - sync_node_is_namespace_root(ctx->local_tree, local_node1) || - sync_node_is_namespace_root(ctx->local_tree, local_node2)) { - *reason_r = "Directory is part of namespace prefix"; - return FALSE; - } return sync_rename_lower_ts(ctx, local_node1, remote_node1, local_node2, remote_node2, reason_r); diff --git a/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c b/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c index 6e556e22b9..98e0c2f896 100644 --- a/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c +++ b/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c @@ -181,7 +181,8 @@ static void test_trees_nofree(struct dsync_mailbox_tree *tree1, dsync_mailbox_tree_build_guid_hash(tree1, &dup_node1, &dup_node2); dsync_mailbox_tree_build_guid_hash(tree2, &dup_node1, &dup_node2); ctx = dsync_mailbox_trees_sync_init(tree1, tree2, - DSYNC_MAILBOX_TREES_SYNC_TYPE_TWOWAY, 0); + DSYNC_MAILBOX_TREES_SYNC_TYPE_TWOWAY, + DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG); while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) { } dsync_mailbox_trees_sync_deinit(&ctx); @@ -681,6 +682,28 @@ static void test_dsync_mailbox_tree_sync_renames20(void) test_end(); } +static void test_dsync_mailbox_tree_sync_renames21(void) +{ +#if 0 + /* FIXME: we can't currently test this without crashing */ + struct dsync_mailbox_tree *tree1, *tree2; + + test_begin("dsync mailbox tree sync renames 21"); + tree1 = dsync_mailbox_tree_init('/', '_'); + tree2 = dsync_mailbox_tree_init('/', '_'); + + node_create(tree1, 1, "INBOX", 0); + node_create(tree1, 2, "foo", 0); + /* swap INBOX and foo - the INBOX name is important since it's + treated specially */ + node_create(tree2, 1, "foo", 0); + node_create(tree2, 2, "INBOX", 1); + + test_trees(tree1, tree2); + test_end(); +#endif +} + static void test_dsync_mailbox_tree_sync_random(void) { struct dsync_mailbox_tree *tree1, *tree2; @@ -717,6 +740,7 @@ int main(void) test_dsync_mailbox_tree_sync_renames18, test_dsync_mailbox_tree_sync_renames19, test_dsync_mailbox_tree_sync_renames20, + test_dsync_mailbox_tree_sync_renames21, test_dsync_mailbox_tree_sync_random, NULL };