]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Initial code to sync mailbox list without dir GUID support.
authorTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 22:19:03 +0000 (17:19 -0500)
committerTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 22:19:03 +0000 (17:19 -0500)
Not complete yet.

--HG--
branch : HEAD

15 files changed:
src/dsync/Makefile.am
src/dsync/dsync-brain.c
src/dsync/dsync-data.c
src/dsync/dsync-data.h
src/dsync/dsync-proxy-client.c
src/dsync/dsync-proxy-server-cmd.c
src/dsync/dsync-proxy.c
src/dsync/dsync-worker-local.c
src/dsync/dsync-worker.c
src/dsync/test-dsync-brain-msgs.c
src/dsync/test-dsync-brain.c
src/dsync/test-dsync-common.c
src/dsync/test-dsync-proxy-server-cmd.c
src/dsync/test-dsync-proxy.c
src/dsync/test-dsync-worker.c

index 2abcea470bbeefa7c293d6628d75c5d0618f56f4..ff6943871eeedb316d3e47375b08b2d0a4e33d91 100644 (file)
@@ -64,12 +64,12 @@ test_dsync_brain_msgs_LDADD = dsync-data.o dsync-brain-msgs.o dsync-worker.o $(t
 test_dsync_brain_msgs_DEPENDENCIES = dsync-data.o dsync-brain-msgs.o dsync-worker.o $(test_libs)
 
 test_dsync_proxy_SOURCES = test-dsync-proxy.c test-dsync-common.c
-test_dsync_proxy_LDADD = dsync-proxy.o $(test_ldadd)
-test_dsync_proxy_DEPENDENCIES = dsync-proxy.o $(test_libs)
+test_dsync_proxy_LDADD = dsync-proxy.o dsync-data.o $(test_ldadd)
+test_dsync_proxy_DEPENDENCIES = dsync-proxy.o dsync-data.o $(test_libs)
 
 test_dsync_proxy_server_cmd_SOURCES = test-dsync-proxy-server-cmd.c test-dsync-worker.c test-dsync-common.c
-test_dsync_proxy_server_cmd_LDADD = dsync-worker.o dsync-proxy.o dsync-proxy-server-cmd.o $(test_ldadd)
-test_dsync_proxy_server_cmd_DEPENDENCIES = dsync-worker.o dsync-proxy.o dsync-proxy-server-cmd.o $(test_libs)
+test_dsync_proxy_server_cmd_LDADD = dsync-worker.o dsync-proxy.o dsync-proxy-server-cmd.o dsync-data.o $(test_ldadd)
+test_dsync_proxy_server_cmd_DEPENDENCIES = dsync-worker.o dsync-proxy.o dsync-proxy-server-cmd.o dsync-data.o $(test_libs)
 
 check: check-am check-test
 check-test: all-am
index 1eb59bf9a7052bf966ceba8dd56b3df823f8d63d..78cff1730a4a0d6c117a20fe0ed0cf5466120ed1 100644 (file)
@@ -92,7 +92,7 @@ static void dsync_worker_mailbox_input(void *context)
                        continue;
 
                dup_box = dsync_mailbox_dup(list->pool, &dsync_box);
-               if (!mail_guid_128_is_empty(dup_box->mailbox_guid.guid))
+               if (!dsync_mailbox_is_noselect(dup_box))
                        array_append(&list->mailboxes, &dup_box, 1);
                else
                        array_append(&list->dirs, &dup_box, 1);
@@ -102,7 +102,7 @@ static void dsync_worker_mailbox_input(void *context)
                if (dsync_worker_mailbox_iter_deinit(&list->iter) < 0)
                        dsync_brain_fail(list->brain);
                array_sort(&list->mailboxes, dsync_mailbox_p_guid_cmp);
-               array_sort(&list->dirs, dsync_mailbox_p_dir_guid_cmp);
+               array_sort(&list->dirs, dsync_mailbox_p_name_cmp);
                dsync_brain_mailbox_list_finished(list->brain);
        }
 }
@@ -542,7 +542,7 @@ static void
 dsync_brain_sync_rename_mailbox(struct dsync_brain *brain,
                                const struct dsync_brain_mailbox *mailbox)
 {
-       if (mailbox->src->last_changed > mailbox->dest->last_changed) {
+       if (mailbox->src->last_change > mailbox->dest->last_change) {
                dsync_worker_rename_mailbox(brain->dest_worker,
                                            &mailbox->box.mailbox_guid,
                                            mailbox->src);
index ad1fe94d252d52ebda9a4d917171c3ba6c11eb68..eedb1d06af93e8b85c02f00deee4190268d3b522 100644 (file)
@@ -62,17 +62,16 @@ int dsync_mailbox_p_guid_cmp(struct dsync_mailbox *const *box1,
        return dsync_mailbox_guid_cmp(*box1, *box2);
 }
 
-int dsync_mailbox_dir_guid_cmp(const struct dsync_mailbox *box1,
-                              const struct dsync_mailbox *box2)
+int dsync_mailbox_name_cmp(const struct dsync_mailbox *box1,
+                          const struct dsync_mailbox *box2)
 {
-       return memcmp(box1->dir_guid.guid, box2->dir_guid.guid,
-                     sizeof(box1->dir_guid.guid));
+       return strcmp(box1->name, box2->name);
 }
 
-int dsync_mailbox_p_dir_guid_cmp(struct dsync_mailbox *const *box1,
-                                struct dsync_mailbox *const *box2)
+int dsync_mailbox_p_name_cmp(struct dsync_mailbox *const *box1,
+                            struct dsync_mailbox *const *box2)
 {
-       return dsync_mailbox_dir_guid_cmp(*box1, *box2);
+       return dsync_mailbox_name_cmp(*box1, *box2);
 }
 
 bool dsync_keyword_list_equals(const char *const *k1, const char *const *k2)
index f303d515763f5f5c97329d142fe8b83ca6f1de47..12f79dc7c40d0ee123f02a023147dbf351ecec53 100644 (file)
@@ -9,26 +9,30 @@ typedef struct {
 ARRAY_DEFINE_TYPE(mailbox_guid, mailbox_guid_t);
 
 enum dsync_mailbox_flags {
-       DSYNC_MAILBOX_FLAG_DELETED_MAILBOX      = 0x01,
-       DSYNC_MAILBOX_FLAG_DELETED_DIR          = 0x02
+       DSYNC_MAILBOX_FLAG_NOSELECT             = 0x01,
+       DSYNC_MAILBOX_FLAG_DELETED_MAILBOX      = 0x02,
+       DSYNC_MAILBOX_FLAG_DELETED_DIR          = 0x04
 };
 
 struct dsync_mailbox {
        const char *name;
        char name_sep;
-       /* Mailbox directory's GUID. Not necessarily set if mailbox is
-          deleted. */
-       mailbox_guid_t dir_guid;
+       /* 128bit SHA1 sum of mailbox name */
+       mailbox_guid_t name_sha1;
        /* Mailbox's GUID. Full of zero with \Noselect mailboxes. */
        mailbox_guid_t mailbox_guid;
 
        uint32_t uid_validity, uid_next;
        uint64_t highest_modseq;
-       time_t last_changed;
+       /* if mailbox is deleted, this is the deletion timestamp.
+          otherwise it's the last rename timestamp. */
+       time_t last_change;
        enum dsync_mailbox_flags flags;
        ARRAY_TYPE(const_string) cache_fields;
 };
 ARRAY_DEFINE_TYPE(dsync_mailbox, struct dsync_mailbox *);
+#define dsync_mailbox_is_noselect(dsync_box) \
+       (((dsync_box)->flags & DSYNC_MAILBOX_FLAG_NOSELECT) != 0)
 
 /* dsync_worker_msg_iter_next() returns also all expunged messages from
    the end of mailbox with this flag set. The GUIDs are 128 bit GUIDs saved
@@ -62,10 +66,10 @@ int dsync_mailbox_guid_cmp(const struct dsync_mailbox *box1,
 int dsync_mailbox_p_guid_cmp(struct dsync_mailbox *const *box1,
                             struct dsync_mailbox *const *box2);
 
-int dsync_mailbox_dir_guid_cmp(const struct dsync_mailbox *box1,
-                              const struct dsync_mailbox *box2);
-int dsync_mailbox_p_dir_guid_cmp(struct dsync_mailbox *const *box1,
-                                struct dsync_mailbox *const *box2);
+int dsync_mailbox_name_cmp(const struct dsync_mailbox *box1,
+                          const struct dsync_mailbox *box2);
+int dsync_mailbox_p_name_cmp(struct dsync_mailbox *const *box1,
+                            struct dsync_mailbox *const *box2);
 
 bool dsync_keyword_list_equals(const char *const *k1, const char *const *k2);
 
index 11319dc6c9db1eff9124f0ae1acd4a8b6031de0b..c3e98db2a639bfb0c5d79afe1eb4d81371ac385f 100644 (file)
@@ -692,7 +692,7 @@ proxy_client_worker_delete_mailbox(struct dsync_worker *_worker,
 
                str_append(str, "BOX-DELETE\t");
                dsync_proxy_mailbox_guid_export(str, &dsync_box->mailbox_guid);
-               str_printfa(str, "\t%s\n", dec2str(dsync_box->last_changed));
+               str_printfa(str, "\t%s\n", dec2str(dsync_box->last_change));
                o_stream_send(worker->output, str_data(str), str_len(str));
        } T_END;
 }
index 879628f713f71cf67635cf3df416cdf452a7f644..6483562c04065e0e3570f2724b687ecaee0f8761 100644 (file)
@@ -256,7 +256,7 @@ cmd_box_delete(struct dsync_proxy_server *server, const char *const *args)
 
        memset(&dsync_box, 0, sizeof(dsync_box));
        dsync_box.mailbox_guid = guid;
-       dsync_box.last_changed = strtoul(args[1], NULL, 10);
+       dsync_box.last_change = strtoul(args[1], NULL, 10);
        dsync_worker_delete_mailbox(server->worker, &dsync_box);
        return 1;
 }
index 1c9c804b64604dc024cc16bc23626d3ea23b3d1e..b58cf8890876f069ac527e0bb94825cf73bd8afb 100644 (file)
@@ -161,15 +161,14 @@ void dsync_proxy_mailbox_export(string_t *str,
        str_append_c(str, '\t');
        s[0] = box->name_sep; s[1] = '\0';
        str_tabescape_write(str, s);
-       str_append_c(str, '\t');
-       dsync_proxy_mailbox_guid_export(str, &box->dir_guid);
-       str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_changed,
+       str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_change,
                    box->flags);
 
-       if (mail_guid_128_is_empty(box->mailbox_guid.guid)) {
-               /* \noselect mailbox */
+       if (dsync_mailbox_is_noselect(box)) {
+               i_assert(box->uid_validity == 0);
                return;
        }
+       i_assert(box->uid_validity != 0);
 
        str_append_c(str, '\t');
        dsync_proxy_mailbox_guid_export(str, &box->mailbox_guid);
@@ -189,13 +188,14 @@ int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args,
        memset(box_r, 0, sizeof(*box_r));
 
        count = str_array_length(args);
-       if (count != 5 && count < 9) {
+       if (count != 4 && count < 8) {
                *error_r = "Mailbox missing parameters";
                return -1;
        }
 
        /* name dir_guid mailbox_guid uid_validity uid_next highest_modseq */
        box_r->name = p_strdup(pool, args[i++]);
+       dsync_str_sha_to_guid(box_r->name, &box_r->name_sha1);
 
        if (strlen(args[i]) != 1) {
                *error_r = "Invalid mailbox name hierarchy separator";
@@ -203,17 +203,14 @@ int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args,
        }
        box_r->name_sep = args[i++][0];
 
-       if (dsync_proxy_mailbox_guid_import(args[i++], &box_r->dir_guid) < 0) {
-               *error_r = "Invalid dir GUID";
-               return -1;
-       }
-       box_r->last_changed = strtoul(args[i++], &p, 10);
+       box_r->last_change = strtoul(args[i++], &p, 10);
        if (*p != '\0') {
-               *error_r = "Invalid mailbox last_renamed";
+               *error_r = "Invalid mailbox last_change";
                return -1;
        }
        box_r->flags = strtoul(args[i++], &p, 10);
-       if (*p != '\0') {
+       if (*p != '\0' ||
+           (dsync_mailbox_is_noselect(box_r) != (args[i] == NULL))) {
                *error_r = "Invalid mailbox flags";
                return -1;
        }
index cc22fac8cb8f2d4bb6ecf9bd644153c0ca65d273..d07c3853a32518647598ab68fc1408065b320297 100644 (file)
@@ -21,6 +21,7 @@ struct local_dsync_worker_mailbox_iter {
        struct dsync_worker_mailbox_iter iter;
        struct mailbox_list_iterate_context *list_iter;
        struct hash_iterate_context *deleted_iter;
+       struct hash_iterate_context *deleted_dir_iter;
 };
 
 struct local_dsync_worker_subs_iter {
@@ -51,16 +52,20 @@ struct local_dsync_mailbox {
 
 struct local_dsync_mailbox_change {
        mailbox_guid_t guid;
-       time_t last_renamed;
-       time_t last_deleted;
+       time_t last_delete;
+
        unsigned int deleted_mailbox:1;
-       unsigned int deleted_dir:1;
 };
-struct local_dsync_subscription_change {
+struct local_dsync_dir_change {
        mailbox_guid_t name_sha1;
        struct mailbox_list *list;
-       time_t last_change;
+
+       time_t last_rename;
+       time_t last_delete;
+       time_t last_subs_change;
+
        unsigned int unsubscribed:1;
+       unsigned int deleted_dir:1;
 };
 
 struct local_dsync_worker {
@@ -72,8 +77,8 @@ struct local_dsync_worker {
        struct hash_table *mailbox_hash;
        /* mailbox_guid_t -> struct local_dsync_mailbox_change* */
        struct hash_table *mailbox_changes_hash;
-       /* mailbox_guid_t -> struct local_dsync_subscription_change */
-       struct hash_table *subscription_changes_hash;
+       /* <-> struct local_dsync_dir_change */
+       struct hash_table *dir_changes_hash;
 
        char alt_char;
 
@@ -190,8 +195,8 @@ static void local_worker_deinit(struct dsync_worker *_worker)
        hash_table_destroy(&worker->mailbox_hash);
        if (worker->mailbox_changes_hash != NULL)
                hash_table_destroy(&worker->mailbox_changes_hash);
-       if (worker->subscription_changes_hash != NULL)
-               hash_table_destroy(&worker->subscription_changes_hash);
+       if (worker->dir_changes_hash != NULL)
+               hash_table_destroy(&worker->dir_changes_hash);
        array_free(&worker->saved_uids);
        pool_unref(&worker->pool);
 }
@@ -227,34 +232,23 @@ dsync_worker_save_mailbox_change(struct local_dsync_worker *worker,
        switch (rec->type) {
        case MAILBOX_LOG_RECORD_DELETE_MAILBOX:
                change->deleted_mailbox = TRUE;
-               if (change->last_deleted < stamp)
-                       change->last_deleted = stamp;
+               if (change->last_delete < stamp)
+                       change->last_delete = stamp;
                break;
        case MAILBOX_LOG_RECORD_DELETE_DIR:
-               change->deleted_dir = TRUE;
-               break;
        case MAILBOX_LOG_RECORD_RENAME:
-               if (change->last_renamed < stamp)
-                       change->last_renamed = stamp;
-               break;
        case MAILBOX_LOG_RECORD_SUBSCRIBE:
        case MAILBOX_LOG_RECORD_UNSUBSCRIBE:
                i_unreached();
        }
-       if (change->deleted_dir && change->deleted_mailbox) {
-               /* same GUID shouldn't be both. something's already
-                  broken, but change this so we don't get into more
-                  problems later. */
-               change->deleted_dir = FALSE;
-       }
 }
 
 static void
-dsync_worker_save_subscription_change(struct local_dsync_worker *worker,
-                                     struct mailbox_list *list,
-                                     const struct mailbox_log_record *rec)
+dsync_worker_save_dir_change(struct local_dsync_worker *worker,
+                            struct mailbox_list *list,
+                            const struct mailbox_log_record *rec)
 {
-       struct local_dsync_subscription_change *change, new_change;
+       struct local_dsync_dir_change *change, new_change;
        time_t stamp;
 
        memset(&new_change, 0, sizeof(new_change));
@@ -263,30 +257,35 @@ dsync_worker_save_subscription_change(struct local_dsync_worker *worker,
               sizeof(new_change.name_sha1.guid));
 
        stamp = mailbox_log_record_get_timestamp(rec);
-       change = hash_table_lookup(worker->subscription_changes_hash,
-                                  &new_change);
+       change = hash_table_lookup(worker->dir_changes_hash, &new_change);
        if (change == NULL) {
-               change = i_new(struct local_dsync_subscription_change, 1);
+               change = i_new(struct local_dsync_dir_change, 1);
                *change = new_change;
-               hash_table_insert(worker->subscription_changes_hash,
-                                 change, change);
-       } else if (change->last_change > stamp) {
-               /* we've already seen a newer subscriptions state. this is
-                  probably a stale record created by dsync */
-               return;
+               hash_table_insert(worker->dir_changes_hash, change, change);
        }
-       change->last_change = stamp;
 
        switch (rec->type) {
        case MAILBOX_LOG_RECORD_DELETE_MAILBOX:
+               i_unreached();
        case MAILBOX_LOG_RECORD_DELETE_DIR:
+               change->deleted_dir = TRUE;
+               if (change->last_delete < stamp)
+                       change->last_delete = stamp;
+               break;
        case MAILBOX_LOG_RECORD_RENAME:
-               i_unreached();
-       case MAILBOX_LOG_RECORD_SUBSCRIBE:
-               change->unsubscribed = FALSE;
+               if (change->last_rename < stamp)
+                       change->last_rename = stamp;
                break;
+       case MAILBOX_LOG_RECORD_SUBSCRIBE:
        case MAILBOX_LOG_RECORD_UNSUBSCRIBE:
-               change->unsubscribed = TRUE;
+               if (change->last_subs_change > stamp) {
+                       /* we've already seen a newer subscriptions state. this
+                          is probably a stale record created by dsync */
+               } else {
+                       change->last_subs_change = stamp;
+                       change->unsubscribed =
+                               rec->type == MAILBOX_LOG_RECORD_UNSUBSCRIBE;
+               }
                break;
        }
 }
@@ -304,14 +303,13 @@ dsync_worker_get_list_mailbox_log(struct local_dsync_worker *worker,
        while ((rec = mailbox_log_iter_next(iter)) != NULL) {
                switch (rec->type) {
                case MAILBOX_LOG_RECORD_DELETE_MAILBOX:
-               case MAILBOX_LOG_RECORD_DELETE_DIR:
-               case MAILBOX_LOG_RECORD_RENAME:
                        dsync_worker_save_mailbox_change(worker, rec);
                        break;
+               case MAILBOX_LOG_RECORD_DELETE_DIR:
+               case MAILBOX_LOG_RECORD_RENAME:
                case MAILBOX_LOG_RECORD_SUBSCRIBE:
                case MAILBOX_LOG_RECORD_UNSUBSCRIBE:
-                       dsync_worker_save_subscription_change(worker,
-                                                             list, rec);
+                       dsync_worker_save_dir_change(worker, list, rec);
                        break;
                }
        }
@@ -333,17 +331,17 @@ static int mailbox_log_record_cmp(const void *p1, const void *p2)
        return memcmp(p1, p2, MAIL_GUID_128_SIZE);
 }
 
-static unsigned int subscription_change_hash(const void *p)
+static unsigned int dir_change_hash(const void *p)
 {
-       const struct local_dsync_subscription_change *change = p;
+       const struct local_dsync_dir_change *change = p;
 
        return mailbox_log_record_hash(change->name_sha1.guid) ^
                POINTER_CAST_TO(change->list, unsigned int);
 }
 
-static int subscription_change_cmp(const void *p1, const void *p2)
+static int dir_change_cmp(const void *p1, const void *p2)
 {
-       const struct local_dsync_subscription_change *c1 = p1, *c2 = p2;
+       const struct local_dsync_dir_change *c1 = p1, *c2 = p2;
 
        if (c1->list != c2->list)
                return 1;
@@ -364,10 +362,9 @@ static int dsync_worker_get_mailbox_log(struct local_dsync_worker *worker)
                hash_table_create(default_pool, worker->pool, 0,
                                  mailbox_log_record_hash,
                                  mailbox_log_record_cmp);
-       worker->subscription_changes_hash =
+       worker->dir_changes_hash =
                hash_table_create(default_pool, worker->pool, 0,
-                                 subscription_change_hash,
-                                 subscription_change_cmp);
+                                 dir_change_hash, dir_change_cmp);
        for (ns = worker->user->namespaces; ns != NULL; ns = ns->next) {
                if (ns->alias_for != NULL)
                        continue;
@@ -420,7 +417,6 @@ iter_next_deleted(struct local_dsync_worker_mailbox_iter *iter,
                  struct local_dsync_worker *worker,
                  struct dsync_mailbox *dsync_box_r)
 {
-       const struct local_dsync_mailbox_change *change;
        void *key, *value;
 
        if (iter->deleted_iter == NULL) {
@@ -428,21 +424,31 @@ iter_next_deleted(struct local_dsync_worker_mailbox_iter *iter,
                        hash_table_iterate_init(worker->mailbox_changes_hash);
        }
        while (hash_table_iterate(iter->deleted_iter, &key, &value)) {
-               change = value;
+               const struct local_dsync_mailbox_change *change = value;
+
                if (change->deleted_mailbox) {
                        /* the name doesn't matter */
                        dsync_box_r->name = "";
                        dsync_box_r->mailbox_guid = change->guid;
-                       dsync_box_r->last_changed = change->last_deleted;
+                       dsync_box_r->last_change = change->last_delete;
                        dsync_box_r->flags |=
                                DSYNC_MAILBOX_FLAG_DELETED_MAILBOX;
                        return 1;
                }
+       }
+
+       if (iter->deleted_dir_iter == NULL) {
+               iter->deleted_dir_iter =
+                       hash_table_iterate_init(worker->dir_changes_hash);
+       }
+       while (hash_table_iterate(iter->deleted_dir_iter, &key, &value)) {
+               const struct local_dsync_dir_change *change = value;
+
                if (change->deleted_dir) {
                        /* the name doesn't matter */
                        dsync_box_r->name = "";
-                       dsync_box_r->dir_guid = change->guid;
-                       dsync_box_r->last_changed = change->last_deleted;
+                       dsync_box_r->name_sha1 = change->name_sha1;
+                       dsync_box_r->last_change = change->last_delete;
                        dsync_box_r->flags |= DSYNC_MAILBOX_FLAG_DELETED_DIR;
                        return 1;
                }
@@ -466,6 +472,7 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
        struct mailbox *box;
        struct mailbox_status status;
        struct local_dsync_mailbox_change *change;
+       struct local_dsync_dir_change *dir_change;
        const char *const *fields;
        unsigned int i, field_count;
 
@@ -478,27 +485,22 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
        storage_name = mail_namespace_get_storage_name(info->ns, info->name);
        dsync_box_r->name = info->name;
        dsync_box_r->name_sep = info->ns->sep;
-       if (mailbox_list_get_guid(info->ns->list, storage_name,
-                                 dsync_box_r->dir_guid.guid) < 0) {
-               i_error("Failed to get dir GUID for mailbox %s: %s", info->name,
-                       mailbox_list_get_last_error(info->ns->list, NULL));
-               _iter->failed = TRUE;
-               return -1;
-       }
 
        /* get last change timestamp */
-       change = hash_table_lookup(worker->mailbox_changes_hash,
-                                  dsync_box_r->dir_guid.guid);
-       if (change != NULL) {
+       dsync_str_sha_to_guid(info->name, &dsync_box_r->name_sha1);
+       dir_change = hash_table_lookup(worker->mailbox_changes_hash,
+                                      dsync_box_r->name_sha1.guid);
+       if (dir_change != NULL) {
                /* it shouldn't be marked as deleted, but drop it to be sure */
-               change->deleted_dir = FALSE;
-               dsync_box_r->last_changed = change->last_renamed;
+               dir_change->deleted_dir = FALSE;
+               dsync_box_r->last_change = dir_change->last_rename;
        }
 
        storage_name = mail_namespace_get_storage_name(info->ns, info->name);
        if ((info->flags & MAILBOX_NOSELECT) != 0) {
+               dsync_box_r->flags |= DSYNC_MAILBOX_FLAG_NOSELECT;
                local_dsync_worker_add_mailbox(worker, info->ns, storage_name,
-                                              &dsync_box_r->dir_guid);
+                                              &dsync_box_r->name_sha1);
                return 1;
        }
 
@@ -584,7 +586,7 @@ local_worker_subs_iter_next(struct dsync_worker_subs_iter *_iter,
                (struct local_dsync_worker_subs_iter *)_iter;
        struct local_dsync_worker *worker =
                (struct local_dsync_worker *)_iter->worker;
-       struct local_dsync_subscription_change *change, change_lookup;
+       struct local_dsync_dir_change *change, change_lookup;
        const struct mailbox_info *info;
        const char *storage_name;
 
@@ -598,13 +600,13 @@ local_worker_subs_iter_next(struct dsync_worker_subs_iter *_iter,
        dsync_str_sha_to_guid(storage_name, &change_lookup.name_sha1);
        change_lookup.list = info->ns->list;
 
-       change = hash_table_lookup(worker->subscription_changes_hash,
+       change = hash_table_lookup(worker->dir_changes_hash,
                                   &change_lookup);
        if (change != NULL) {
                /* it shouldn't be marked as unsubscribed, but drop it to
                   be sure */
                change->unsubscribed = FALSE;
-               rec_r->last_change = change->last_change;
+               rec_r->last_change = change->last_subs_change;
        }
        rec_r->ns_prefix = info->ns->prefix;
        rec_r->vname = info->name;
@@ -624,10 +626,10 @@ local_worker_subs_iter_next_un(struct dsync_worker_subs_iter *_iter,
 
        if (iter->deleted_iter == NULL) {
                iter->deleted_iter =
-                       hash_table_iterate_init(worker->subscription_changes_hash);
+                       hash_table_iterate_init(worker->dir_changes_hash);
        }
        while (hash_table_iterate(iter->deleted_iter, &key, &value)) {
-               const struct local_dsync_subscription_change *change = value;
+               const struct local_dsync_dir_change *change = value;
 
                if (change->unsubscribed) {
                        /* the name doesn't matter */
@@ -636,7 +638,7 @@ local_worker_subs_iter_next_un(struct dsync_worker_subs_iter *_iter,
                        memset(rec_r, 0, sizeof(*rec_r));
                        rec_r->name_sha1 = change->name_sha1;
                        rec_r->ns_prefix = ns->prefix;
-                       rec_r->last_change = change->last_change;
+                       rec_r->last_change = change->last_subs_change;
                        return 1;
                }
        }
@@ -1113,7 +1115,7 @@ local_worker_delete_mailbox(struct dsync_worker *_worker,
        }
 
        mailbox_list_set_changelog_timestamp(lbox->ns->list,
-                                            dsync_box->last_changed);
+                                            dsync_box->last_change);
        if (mailbox_list_delete_mailbox(lbox->ns->list,
                                        lbox->storage_name) < 0) {
                i_error("Can't delete mailbox %s: %s", lbox->storage_name,
@@ -1123,32 +1125,6 @@ local_worker_delete_mailbox(struct dsync_worker *_worker,
        mailbox_list_set_changelog_timestamp(lbox->ns->list, (time_t)-1);
 }
 
-static void
-local_worker_rename_children(struct local_dsync_worker *worker,
-                            const char *oldname, const char *newname, char sep)
-{
-       struct hash_iterate_context *iter;
-       const char *oldprefix;
-       void *key, *value;
-       unsigned int oldprefix_len;
-
-       oldprefix = t_strdup_printf("%s%c", oldname, sep);
-       oldprefix_len = strlen(oldprefix);
-
-       iter = hash_table_iterate_init(worker->mailbox_hash);
-       while (hash_table_iterate(iter, &key, &value)) {
-               struct local_dsync_mailbox *lbox = value;
-
-               if (strncmp(lbox->storage_name, oldprefix, oldprefix_len) != 0)
-                       continue;
-
-               lbox->storage_name =
-                       p_strdup_printf(worker->pool, "%s%c%s", newname, sep,
-                                       lbox->storage_name + oldprefix_len);
-       }
-       hash_table_iterate_deinit(&iter);
-}
-
 static void
 local_worker_rename_mailbox(struct dsync_worker *_worker,
                            const mailbox_guid_t *mailbox,
@@ -1158,7 +1134,7 @@ local_worker_rename_mailbox(struct dsync_worker *_worker,
                (struct local_dsync_worker *)_worker;
        struct local_dsync_mailbox *lbox;
        struct mailbox_list *list;
-       const char *oldname, *newname;
+       const char *newname;
 
        lbox = hash_table_lookup(worker->mailbox_hash, mailbox);
        if (lbox == NULL) {
@@ -1177,17 +1153,14 @@ local_worker_rename_mailbox(struct dsync_worker *_worker,
                return;
        }
 
-       mailbox_list_set_changelog_timestamp(list, dsync_box->last_changed);
+       mailbox_list_set_changelog_timestamp(list, dsync_box->last_change);
        if (mailbox_list_rename_mailbox(list, lbox->storage_name,
-                                       list, newname, TRUE) < 0) {
+                                       list, newname, FALSE) < 0) {
                i_error("Can't rename mailbox %s to %s: %s", lbox->storage_name,
                        newname, mailbox_list_get_last_error(list, NULL));
                dsync_worker_set_failure(_worker);
        } else {
-               oldname = lbox->storage_name;
                lbox->storage_name = p_strdup(worker->pool, newname);
-               local_worker_rename_children(worker, oldname, newname,
-                                            lbox->ns->sep);
        }
        mailbox_list_set_changelog_timestamp(list, (time_t)-1);
 }
index c528a5d896fb4c0c48167223476de226faf0de77..b50c4ab62958580bf3282aed3d360b2ef114f1dd 100644 (file)
@@ -125,7 +125,7 @@ void dsync_worker_create_mailbox(struct dsync_worker *worker,
                                 const struct dsync_mailbox *dsync_box)
 {
        i_assert(dsync_box->uid_validity != 0 ||
-                mail_guid_128_is_empty(dsync_box->mailbox_guid.guid));
+                dsync_mailbox_is_noselect(dsync_box));
 
        if (!worker->readonly)
                worker->v.create_mailbox(worker, dsync_box);
index ee60fe877f98c8036abc3d861e9a623ffdc465f5..d6cdf50428370b537d21305b81ff48831f194494 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "array.h"
-#include "sha1.h"
 #include "crc32.h"
 #include "dsync-brain-private.h"
 #include "test-dsync-worker.h"
@@ -54,10 +53,8 @@ test_box_has_guid(const char *name, const mailbox_guid_t *guid)
 static struct test_dsync_mailbox *
 test_box_add(enum test_box_add_type type, const char *name)
 {
-       unsigned char sha[SHA1_RESULTLEN];
        struct test_dsync_mailbox *tbox;
        struct dsync_mailbox *box;
-       const char *dir_name;
 
        tbox = test_box_find(name);
        if (tbox == NULL) {
@@ -69,12 +66,9 @@ test_box_add(enum test_box_add_type type, const char *name)
        box = i_new(struct dsync_mailbox, 1);
        box->name = i_strdup(name);
 
-       sha1_get_digest(name, strlen(name), sha);
-       memcpy(box->mailbox_guid.guid, sha, sizeof(box->mailbox_guid.guid));
-
-       dir_name = t_strconcat("dir-", name, NULL);
-       sha1_get_digest(dir_name, strlen(dir_name), sha);
-       memcpy(box->dir_guid.guid, sha, sizeof(box->dir_guid.guid));
+       dsync_str_sha_to_guid(t_strconcat("box-", name, NULL),
+                             &box->mailbox_guid);
+       dsync_str_sha_to_guid(name, &box->name_sha1);
 
        box->uid_validity = crc32_str(name);
        box->highest_modseq = 1;
@@ -93,7 +87,7 @@ test_box_add(enum test_box_add_type type, const char *name)
        }
        tbox->box.box.name = box->name;
        tbox->box.box.mailbox_guid = box->mailbox_guid;
-       tbox->box.box.dir_guid = box->dir_guid;
+       tbox->box.box.name_sha1 = box->name_sha1;
        tbox->box.box.uid_validity = box->uid_validity;
        return tbox;
 }
index f7a29cfb8939faa30e43dcbbc6267d24a21605ce..12b7f45a9d657fb9d0ab93ff3f49db22ec842a38 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "array.h"
-#include "sha1.h"
 #include "master-service.h"
 #include "dsync-brain-private.h"
 #include "test-dsync-worker.h"
@@ -39,18 +38,10 @@ void dsync_brain_msg_sync_resolve_uid_conflicts(struct dsync_brain_mailbox_sync
 
 static void mailboxes_set_guids(struct dsync_mailbox *boxes)
 {
-       unsigned char sha[SHA1_RESULTLEN];
-       const char *dir_name;
-
        for (; boxes->name != NULL; boxes++) {
-               sha1_get_digest(boxes->name, strlen(boxes->name), sha);
-               memcpy(boxes->mailbox_guid.guid, sha,
-                      sizeof(boxes->mailbox_guid.guid));
-
-               dir_name = t_strconcat("dir-", boxes->name, NULL);
-               sha1_get_digest(dir_name, strlen(dir_name), sha);
-               memcpy(boxes->dir_guid.guid, sha,
-                      sizeof(boxes->dir_guid.guid));
+               dsync_str_sha_to_guid(t_strconcat("box-", boxes->name, NULL),
+                                     &boxes->mailbox_guid);
+               dsync_str_sha_to_guid(boxes->name, &boxes->name_sha1);
        }
 }
 
@@ -81,8 +72,8 @@ test_dsync_mailbox_create_equals(const struct dsync_mailbox *cbox,
        return strcmp(cbox->name, obox->name) == 0 &&
                memcmp(cbox->mailbox_guid.guid, obox->mailbox_guid.guid,
                       sizeof(cbox->mailbox_guid.guid)) == 0 &&
-               memcmp(cbox->dir_guid.guid, obox->dir_guid.guid,
-                      sizeof(cbox->dir_guid.guid)) == 0 &&
+               memcmp(cbox->name_sha1.guid, obox->name_sha1.guid,
+                      sizeof(cbox->name_sha1.guid)) == 0 &&
                cbox->uid_validity == obox->uid_validity &&
                cbox->uid_next == 0 && cbox->highest_modseq == 0;
 }
@@ -93,7 +84,7 @@ test_dsync_mailbox_delete_equals(const struct dsync_mailbox *dbox,
 {
        return memcmp(dbox->mailbox_guid.guid, obox->mailbox_guid.guid,
                      sizeof(dbox->mailbox_guid.guid)) == 0 &&
-               dbox->last_changed == obox->last_changed;
+               dbox->last_change == obox->last_change;
 }
 
 static void
@@ -174,10 +165,6 @@ static void test_dsync_brain(void)
        test_assert(brain->state == DSYNC_STATE_SYNC_MSGS);
 
        /* check that it created/deleted missing mailboxes */
-       test_assert(test_dsync_worker_next_box_event(dest_test_worker, &box_event));
-       test_assert(box_event.type == LAST_BOX_TYPE_CREATE);
-       test_assert(test_dsync_mailbox_create_equals(&box_event.box, &src_boxes[6]));
-
        test_assert(test_dsync_worker_next_box_event(dest_test_worker, &box_event));
        test_assert(box_event.type == LAST_BOX_TYPE_DELETE);
        test_assert(test_dsync_mailbox_delete_equals(&box_event.box, &dest_boxes[8]));
@@ -186,6 +173,10 @@ static void test_dsync_brain(void)
        test_assert(box_event.type == LAST_BOX_TYPE_DELETE);
        test_assert(test_dsync_mailbox_delete_equals(&box_event.box, &src_boxes[7]));
 
+       test_assert(test_dsync_worker_next_box_event(dest_test_worker, &box_event));
+       test_assert(box_event.type == LAST_BOX_TYPE_CREATE);
+       test_assert(test_dsync_mailbox_create_equals(&box_event.box, &src_boxes[6]));
+
        test_assert(test_dsync_worker_next_box_event(src_test_worker, &box_event));
        test_assert(box_event.type == LAST_BOX_TYPE_CREATE);
        test_assert(test_dsync_mailbox_create_equals(&box_event.box, &dest_boxes[6]));
index f0c8f52d7995771b3566b13c4606853c5ae4e750..6dee8b88023f54af07c2cad13ffcbf4a09a28b24 100644 (file)
@@ -48,8 +48,6 @@ bool dsync_mailboxes_equal(const struct dsync_mailbox *box1,
 
        if (strcmp(box1->name, box2->name) != 0 ||
            box1->name_sep != box2->name_sep ||
-           memcmp(box1->dir_guid.guid, box2->dir_guid.guid,
-                  sizeof(box1->dir_guid.guid)) != 0 ||
            memcmp(box1->mailbox_guid.guid, box2->mailbox_guid.guid,
                   sizeof(box1->mailbox_guid.guid)) != 0 ||
            box1->uid_validity != box2->uid_validity ||
index 2ceaf09ef17695bc99a6c926bd2209d5c5b2da50..cb19fefa850b3b07794a254b595647320d201340 100644 (file)
@@ -75,20 +75,18 @@ static void test_dsync_proxy_box_list(void)
        memset(&box, 0, sizeof(box));
        box.name = "\t\001\r\nname\t\001\n\r";
        box.name_sep = '/';
-       box.last_changed = 992;
-       box.flags = 123;
-       memcpy(box.dir_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE);
+       box.last_change = 992;
+       box.flags = DSYNC_MAILBOX_FLAG_NOSELECT;
        test_worker->box_iter.next_box = &box;
        test_assert(run_more() == 0);
        test_assert(strcmp(str_c(out), t_strconcat(str_tabescape(box.name),
-               "\t/\t"TEST_MAILBOX_GUID1"\t992\t123\n", NULL)) == 0);
+               "\t/\t992\t1\n", NULL)) == 0);
        out_clear();
 
        /* selectable mailbox */
        memset(&box, 0, sizeof(box));
        box.name = "foo/bar";
        box.name_sep = '/';
-       memcpy(box.dir_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE);
        memcpy(box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE);
        box.uid_validity = 4275878552;
        box.uid_next = 4023233417;
@@ -97,8 +95,7 @@ static void test_dsync_proxy_box_list(void)
 
        test_assert(run_more() == 0);
 
-       test_assert(strcmp(str_c(out), "foo/bar\t/\t"
-                          TEST_MAILBOX_GUID2"\t0\t0\t"
+       test_assert(strcmp(str_c(out), "foo/bar\t/\t0\t0\t"
                           TEST_MAILBOX_GUID1"\t"
                           "4275878552\t"
                           "4023233417\t"
@@ -221,30 +218,28 @@ static void test_dsync_proxy_box_create(void)
        test_begin("proxy server box create");
 
        test_assert(run_cmd("BOX-CREATE", "noselect", "/",
-                           TEST_MAILBOX_GUID2, "553", "99", NULL) == 1);
+                           "553", "1", NULL) == 1);
        test_assert(test_dsync_worker_next_box_event(test_worker, &event));
        test_assert(event.type == LAST_BOX_TYPE_CREATE);
        test_assert(strcmp(event.box.name, "noselect") == 0);
        test_assert(event.box.name_sep == '/');
-       test_assert(memcmp(event.box.dir_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
-       test_assert(event.box.last_changed == 553);
-       test_assert(event.box.flags == 99);
+       test_assert(event.box.last_change == 553);
+       test_assert(event.box.flags == DSYNC_MAILBOX_FLAG_NOSELECT);
        test_assert(event.box.uid_validity == 0);
 
-       test_assert(run_cmd("BOX-CREATE", "selectable", "?", TEST_MAILBOX_GUID1,
+       test_assert(run_cmd("BOX-CREATE", "selectable", "?",
                            "61", "2", TEST_MAILBOX_GUID2, "1234567890", "9876",
                            "28427847284728", NULL) == 1);
        test_assert(test_dsync_worker_next_box_event(test_worker, &event));
        test_assert(event.type == LAST_BOX_TYPE_CREATE);
        test_assert(strcmp(event.box.name, "selectable") == 0);
        test_assert(event.box.name_sep == '?');
-       test_assert(memcmp(event.box.dir_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
        test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
        test_assert(event.box.flags == 2);
        test_assert(event.box.uid_validity == 1234567890);
        test_assert(event.box.uid_next == 9876);
        test_assert(event.box.highest_modseq == 28427847284728);
-       test_assert(event.box.last_changed == 61);
+       test_assert(event.box.last_change == 61);
 
        test_end();
 }
@@ -259,13 +254,13 @@ static void test_dsync_proxy_box_delete(void)
        test_assert(test_dsync_worker_next_box_event(test_worker, &event));
        test_assert(event.type == LAST_BOX_TYPE_DELETE);
        test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
-       test_assert(event.box.last_changed == 4351);
+       test_assert(event.box.last_change == 4351);
 
        test_assert(run_cmd("BOX-DELETE", TEST_MAILBOX_GUID2, "653", NULL) == 1);
        test_assert(test_dsync_worker_next_box_event(test_worker, &event));
        test_assert(event.type == LAST_BOX_TYPE_DELETE);
        test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
-       test_assert(event.box.last_changed == 653);
+       test_assert(event.box.last_change == 653);
 
        test_end();
 }
@@ -299,20 +294,19 @@ static void test_dsync_proxy_box_update(void)
 
        test_begin("proxy server box update");
 
-       test_assert(run_cmd("BOX-UPDATE", "updated", "/", TEST_MAILBOX_GUID2,
-                           "53", "9", TEST_MAILBOX_GUID1, "34343", "22",
+       test_assert(run_cmd("BOX-UPDATE", "updated", "/",
+                           "53", "2", TEST_MAILBOX_GUID1, "34343", "22",
                            "2238427847284728", NULL) == 1);
        test_assert(test_dsync_worker_next_box_event(test_worker, &event));
        test_assert(event.type == LAST_BOX_TYPE_UPDATE);
        test_assert(strcmp(event.box.name, "updated") == 0);
        test_assert(event.box.name_sep == '/');
-       test_assert(memcmp(event.box.dir_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE) == 0);
        test_assert(memcmp(event.box.mailbox_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE) == 0);
-       test_assert(event.box.flags == 9);
+       test_assert(event.box.flags == DSYNC_MAILBOX_FLAG_DELETED_MAILBOX);
        test_assert(event.box.uid_validity == 34343);
        test_assert(event.box.uid_next == 22);
        test_assert(event.box.highest_modseq == 2238427847284728);
-       test_assert(event.box.last_changed == 53);
+       test_assert(event.box.last_change == 53);
 
        test_end();
 }
index 679088fda8c3fbf674eda82841c2068caec511ef..6292420b4c6ffdb9e0f0146186ee933659a52f94 100644 (file)
@@ -103,8 +103,7 @@ static void test_dsync_proxy_mailbox(void)
        /* test \noselect mailbox */
        box_in.name = "\t\001\r\nname\t\001\n\r";
        box_in.name_sep = '/';
-       box_in.flags = 1234567890;
-       memcpy(box_in.dir_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE);
+       box_in.flags = DSYNC_MAILBOX_FLAG_NOSELECT;
        dsync_proxy_mailbox_export(str, &box_in);
        test_assert(dsync_proxy_mailbox_import(pool, str_c(str),
                                               &box_out, &error) == 0);
@@ -113,8 +112,7 @@ static void test_dsync_proxy_mailbox(void)
        /* real mailbox */
        i_assert(sizeof(box_in.mailbox_guid.guid) == sizeof(test_mailbox_guid1));
        memcpy(box_in.mailbox_guid.guid, test_mailbox_guid2, MAIL_GUID_128_SIZE);
-       memcpy(box_in.dir_guid.guid, test_mailbox_guid1, MAIL_GUID_128_SIZE);
-       box_in.flags = 24242;
+       box_in.flags = 24242 & ~DSYNC_MAILBOX_FLAG_NOSELECT;
        box_in.uid_validity = 0xf74d921b;
        box_in.uid_next = 73529472;
        box_in.highest_modseq = 0x123456789abcdef0ULL;
index 916791537f19c7860641ad0a9dea573b5282173e..acc0638e605f84cca34edc8ba397e3640a1e87f6 100644 (file)
@@ -218,7 +218,7 @@ test_worker_set_subscribed(struct dsync_worker *_worker,
 
        memset(&dsync_box, 0, sizeof(dsync_box));
        dsync_box.name = name;
-       dsync_box.last_changed = last_change;
+       dsync_box.last_change = last_change;
        test_worker_set_last_box(_worker, &dsync_box,
                                 set ? LAST_BOX_TYPE_SUBSCRIBE :
                                 LAST_BOX_TYPE_UNSUBSCRIBE);