]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Don't try to rename namespace roots.
authorTimo Sirainen <tss@iki.fi>
Wed, 6 May 2015 13:16:11 +0000 (16:16 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 6 May 2015 13:16:11 +0000 (16:16 +0300)
It'll just cause an assert-crash.

src/doveadm/dsync/dsync-mailbox-tree-sync.c
src/doveadm/dsync/test-dsync-mailbox-tree-sync.c

index c4b83caf401a24ad9b190d0b80e324741c2dade0..f0a149e8df508a61a33a2827920c572411a51e96 100644 (file)
@@ -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);
index 6e556e22b91640f01513345127dba126eef039fe..98e0c2f896a9570e00414f74c6ca137dd1998e34 100644 (file)
@@ -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
        };