Mercurial > dovecot > core-2.2
diff src/dsync/dsync-brain.c @ 9686:4d5cc6ce68aa HEAD
dsync: Lots of improvements and fixes. Appears to be somewhat working now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 27 Jul 2009 19:04:36 -0400 |
parents | 16849c0931be |
children | d9a96da46d4a |
line wrap: on
line diff
--- a/src/dsync/dsync-brain.c Mon Jul 27 19:02:12 2009 -0400 +++ b/src/dsync/dsync-brain.c Mon Jul 27 19:04:36 2009 -0400 @@ -3,27 +3,27 @@ #include "lib.h" #include "array.h" #include "hash.h" -#include "hex-binary.h" #include "master-service.h" #include "dsync-worker.h" #include "dsync-brain-private.h" static void dsync_brain_mailbox_list_deinit(struct dsync_brain_mailbox_list **list); -static void dsync_brain_msg_sync_deinit(struct dsync_brain_mailbox_sync **sync); struct dsync_brain *dsync_brain_init(struct dsync_worker *src_worker, - struct dsync_worker *dest_worker) + struct dsync_worker *dest_worker, + enum dsync_brain_flags flags) { struct dsync_brain *brain; brain = i_new(struct dsync_brain, 1); brain->src_worker = src_worker; brain->dest_worker = dest_worker; + brain->flags = flags; return brain; } -static void dsync_brain_fail(struct dsync_brain *brain) +void dsync_brain_fail(struct dsync_brain *brain) { brain->failed = TRUE; master_service_stop(master_service); @@ -118,7 +118,7 @@ memset(&new_box, 0, sizeof(new_box)); - /* find mailboxes from source whose GUIDs don't exist in dest. + /* find mailboxes from whose GUIDs don't exist. the mailboxes are sorted by GUID, so we can do this quickly. */ src_boxes = array_get(&brain->src_mailbox_list->mailboxes, &src_count); dest_boxes = array_get(&brain->dest_mailbox_list->mailboxes, &dest_count); @@ -136,6 +136,11 @@ src++; } else { /* exists only in dest */ + new_box = *dest_boxes[dest]; + new_box.uid_next = 0; + new_box.highest_modseq = 0; + dsync_worker_create_mailbox(brain->src_worker, + &new_box); dest++; } } @@ -145,271 +150,12 @@ new_box.highest_modseq = 0; dsync_worker_create_mailbox(brain->dest_worker, &new_box); } -} - -static void dsync_brain_guid_add(struct dsync_brain_mailbox_sync *sync, - struct dsync_brain_msg_iter *iter) -{ - struct dsync_brain_guid_instance *inst, *prev_inst; - - inst = p_new(sync->pool, struct dsync_brain_guid_instance, 1); - inst->mailbox_idx = iter->mailbox_idx; - inst->uid = iter->msg.uid; - - prev_inst = hash_table_lookup(sync->guid_hash, iter->msg.guid); - if (prev_inst == NULL) { - hash_table_insert(sync->guid_hash, - p_strdup(sync->pool, iter->msg.guid), inst); - } else { - inst->next = prev_inst->next; - prev_inst->next = inst; - } -} - -static int dsync_brain_msg_iter_next(struct dsync_brain_msg_iter *iter) -{ - int ret = 1; - - if (iter->msg.guid == NULL) { - ret = dsync_worker_msg_iter_next(iter->iter, &iter->mailbox_idx, - &iter->msg); - if (ret > 0) { - if (iter->save_guids) - dsync_brain_guid_add(iter->sync, iter); - } - } - - if (iter->wanted_mailbox_idx != iter->mailbox_idx) { - /* finished with this mailbox */ - return -1; - } - return ret; -} - -static int dsync_brain_msg_iter_next_pair(struct dsync_brain_mailbox_sync *sync) -{ - int ret; - - if ((ret = dsync_brain_msg_iter_next(sync->src_msg_iter)) <= 0) - return ret; - if ((ret = dsync_brain_msg_iter_next(sync->dest_msg_iter)) <= 0) - return ret; - return 1; -} - -static void -dsync_brain_msg_sync_save_source(struct dsync_brain_mailbox_sync *sync) -{ - struct dsync_brain_new_msg *new_msg; - - new_msg = array_append_space(&sync->new_msgs); - new_msg->mailbox_idx = sync->src_msg_iter->mailbox_idx; - new_msg->msg = dsync_message_dup(sync->pool, &sync->src_msg_iter->msg); -} - -static void dsync_brain_msg_sync_existing(struct dsync_brain *brain, - struct dsync_message *src_msg, - struct dsync_message *dest_msg) -{ - if (src_msg->flags != dest_msg->flags || - src_msg->modseq > dest_msg->modseq || - !dsync_keyword_list_equals(src_msg->keywords, dest_msg->keywords)) - dsync_worker_msg_update_metadata(brain->dest_worker, src_msg); -} - -static const char * -get_guid_128_str(const char *guid, unsigned char *dest, unsigned int dest_len) -{ - uint8_t guid_128[MAIL_GUID_128_SIZE]; - buffer_t guid_128_buf; - - buffer_create_data(&guid_128_buf, dest, dest_len); - mail_generate_guid_128_hash(guid, guid_128); - if (mail_guid_128_is_empty(guid_128)) - return ""; - binary_to_hex_append(&guid_128_buf, guid_128, sizeof(guid_128)); - buffer_append_c(&guid_128_buf, '\0'); - return guid_128_buf.data; -} - -static int dsync_brain_msg_sync_pair(struct dsync_brain_mailbox_sync *sync) -{ - struct dsync_message *src_msg = &sync->src_msg_iter->msg; - struct dsync_message *dest_msg = &sync->dest_msg_iter->msg; - struct dsync_mailbox *const *boxp; - struct dsync_brain_uid_conflict *conflict; - const char *src_guid, *dest_guid; - unsigned char guid_128_data[MAIL_GUID_128_SIZE * 2 + 1]; - bool src_expunged, dest_expunged; - - src_expunged = (src_msg->flags & DSYNC_MAIL_FLAG_EXPUNGED) != 0; - dest_expunged = (dest_msg->flags & DSYNC_MAIL_FLAG_EXPUNGED) != 0; - - if (src_expunged) { - src_guid = src_msg->guid; - dest_guid = get_guid_128_str(dest_msg->guid, guid_128_data, - sizeof(guid_128_data)); - } else if (dest_expunged) { - src_guid = get_guid_128_str(src_msg->guid, guid_128_data, - sizeof(guid_128_data)); - dest_guid = dest_msg->guid; - } else { - src_guid = src_msg->guid; - dest_guid = dest_msg->guid; - } - - if (src_msg->uid < dest_msg->uid) { - /* message has been expunged from dest. ignore it, unless - we're in uid-conflict mode. */ - if (sync->uid_conflict && !src_expunged) - dsync_brain_msg_sync_save_source(sync); - src_msg->guid = NULL; - return 0; - } else if (src_msg->uid > dest_msg->uid) { - /* message has been expunged from src. expunge it from dest - too, unless we're in uid-conflict mode. */ - if (!sync->uid_conflict && !dest_expunged) { - dsync_worker_msg_expunge(sync->brain->dest_worker, - dest_msg->uid); - } - dest_msg->guid = NULL; - return 0; + for (; dest < dest_count; dest++) { + new_box = *dest_boxes[dest]; + new_box.uid_next = 0; + new_box.highest_modseq = 0; + dsync_worker_create_mailbox(brain->src_worker, &new_box); } - - /* UIDs match, but do GUIDs? If either of the GUIDs aren't set, it - means that either the storage doesn't support GUIDs or we're - handling an old-style expunge record. In that case just assume - they match. */ - if (strcmp(src_guid, dest_guid) != 0 && - *src_guid != '\0' && *dest_guid != '\0') { - /* UID conflict. give new UIDs to messages in both src and - dest (if they're not expunged already) */ - sync->uid_conflict = TRUE; - if (!dest_expunged) { - conflict = array_append_space(&sync->uid_conflicts); - conflict->mailbox_idx = sync->src_msg_iter->mailbox_idx; - conflict->uid = dest_msg->uid; - } - if (!src_expunged) { - boxp = array_idx(&sync->brain->src_mailbox_list->mailboxes, - conflict->mailbox_idx); - src_msg->uid = (*boxp)->uid_next++; - dsync_brain_msg_sync_save_source(sync); - } - } else if (dest_expunged) { - /* message expunged from destination, we can skip this. */ - } else if (src_expunged) { - /* message expunged from source, expunge from destination too */ - dsync_worker_msg_expunge(sync->brain->dest_worker, - dest_msg->uid); - } else { - /* message exists in both source and dest, sync metadata */ - dsync_brain_msg_sync_existing(sync->brain, src_msg, dest_msg); - } - src_msg->guid = NULL; - dest_msg->guid = NULL; - return 0; -} - -static bool -dsync_brain_msg_sync_mailbox_more(struct dsync_brain_mailbox_sync *sync) -{ - struct dsync_mailbox *const *boxp; - int ret; - - while ((ret = dsync_brain_msg_iter_next_pair(sync)) > 0) { - if (dsync_brain_msg_sync_pair(sync) < 0) - break; - if (dsync_worker_is_output_full(sync->brain->dest_worker)) - return FALSE; - } - if (ret == 0) - return FALSE; - - /* finished syncing messages in this mailbox that exist in both source - and destination. if there are messages left in destination, - we can't reliably know if they should be expunged, so don't. - Add their GUIDs to hash in any case. */ - - boxp = array_idx(&sync->brain->src_mailbox_list->mailboxes, - sync->src_msg_iter->wanted_mailbox_idx); - while ((ret = dsync_brain_msg_iter_next(sync->dest_msg_iter)) > 0) { - if (sync->dest_msg_iter->msg.uid >= (*boxp)->uid_next) - sync->uid_conflict = TRUE; - sync->dest_msg_iter->msg.guid = NULL; - } - if (ret == 0) - return FALSE; - - /* if there are any messages left in source, we'll copy all of them */ - while ((ret = dsync_brain_msg_iter_next(sync->src_msg_iter)) > 0) { - dsync_brain_msg_sync_save_source(sync); - sync->src_msg_iter->msg.guid = NULL; - } - if (ret == 0) - return FALSE; - /* done with this mailbox. the same iterator is still used for - getting messages from other mailboxes. */ - return TRUE; -} - -static void dsync_brain_msg_sync_finish(struct dsync_brain_mailbox_sync *sync) -{ - /* synced all existing messages. now add the new messages. */ - if (dsync_worker_msg_iter_deinit(&sync->src_msg_iter->iter) < 0 || - dsync_worker_msg_iter_deinit(&sync->dest_msg_iter->iter)) - dsync_brain_fail(sync->brain); - - sync->brain->state++; - dsync_brain_sync(sync->brain); -} - -static void dsync_brain_msg_sync_more(struct dsync_brain_mailbox_sync *sync) -{ - struct dsync_mailbox *const *mailboxes; - unsigned int count, mailbox_idx; - - mailboxes = array_get(&sync->brain->src_mailbox_list->mailboxes, - &count); - while (dsync_brain_msg_sync_mailbox_more(sync)) { - /* sync the next mailbox */ - sync->uid_conflict = FALSE; - mailbox_idx = ++sync->src_msg_iter->wanted_mailbox_idx; - sync->dest_msg_iter->wanted_mailbox_idx++; - if (mailbox_idx == count) { - dsync_brain_msg_sync_finish(sync); - return; - } - dsync_worker_select_mailbox(sync->brain->dest_worker, - &mailboxes[mailbox_idx]->guid); - } -} - -static void dsync_worker_msg_callback(void *context) -{ - struct dsync_brain_mailbox_sync *sync = context; - - dsync_brain_msg_sync_more(sync); -} - -static struct dsync_brain_msg_iter * -dsync_brain_msg_iter_init(struct dsync_brain_mailbox_sync *sync, - struct dsync_worker *worker, - const mailbox_guid_t mailboxes[], - unsigned int mailbox_count) -{ - struct dsync_brain_msg_iter *iter; - - iter = p_new(sync->pool, struct dsync_brain_msg_iter, 1); - iter->sync = sync; - iter->worker = worker; - iter->iter = dsync_worker_msg_iter_init(worker, mailboxes, - mailbox_count); - dsync_worker_set_input_callback(worker, - dsync_worker_msg_callback, sync); - dsync_worker_set_output_callback(worker, - dsync_worker_msg_callback, sync); - return iter; } static bool dsync_mailbox_has_changed_msgs(const struct dsync_mailbox *box1, @@ -422,9 +168,11 @@ static void dsync_brain_get_changed_mailboxes(struct dsync_brain *brain, - ARRAY_TYPE(mailbox_guid) *guids) + ARRAY_TYPE(dsync_brain_mailbox) *brain_boxes, + bool full_sync) { struct dsync_mailbox *const *src_boxes, *const *dest_boxes; + struct dsync_brain_mailbox *brain_box; unsigned int src, dest, src_count, dest_count; int ret; @@ -434,297 +182,70 @@ for (src = dest = 0; src < src_count && dest < dest_count; ) { ret = dsync_mailbox_guid_cmp(src_boxes[src], dest_boxes[dest]); if (ret == 0) { - if (dsync_mailbox_has_changed_msgs(src_boxes[src], - dest_boxes[dest])) - array_append(guids, &src_boxes[src]->guid, 1); + if (full_sync || + dsync_mailbox_has_changed_msgs(src_boxes[src], + dest_boxes[dest])) { + brain_box = array_append_space(brain_boxes); + brain_box->box = *src_boxes[src]; + + brain_box->box.highest_modseq = + I_MAX(src_boxes[src]->highest_modseq, + dest_boxes[dest]->highest_modseq); + brain_box->box.uid_next = + I_MAX(src_boxes[src]->uid_next, + dest_boxes[dest]->uid_next); + brain_box->src = src_boxes[src]; + brain_box->dest = dest_boxes[dest]; + } src++; dest++; } else if (ret < 0) { /* exists only in source */ - array_append(guids, &src_boxes[src]->guid, 1); + brain_box = array_append_space(brain_boxes); + brain_box->box = *src_boxes[src]; + brain_box->src = src_boxes[src]; src++; } else { /* exists only in dest */ + brain_box = array_append_space(brain_boxes); + brain_box->box = *dest_boxes[dest]; + brain_box->dest = dest_boxes[dest]; dest++; } } - for (; src < src_count; src++) - array_append(guids, &src_boxes[src]->guid, 1); -} - -static struct dsync_brain_mailbox_sync * -dsync_brain_msg_sync_init(struct dsync_brain *brain) -{ - struct dsync_brain_mailbox_sync *sync; - ARRAY_TYPE(mailbox_guid) guids; - unsigned int count; - pool_t pool; - - t_array_init(&guids, array_count(&brain->src_mailbox_list->mailboxes)); - dsync_brain_get_changed_mailboxes(brain, &guids); - - pool = pool_alloconly_create("dsync brain mailbox sync", 1024*256); - sync = p_new(pool, struct dsync_brain_mailbox_sync, 1); - sync->pool = pool; - sync->brain = brain; - - i_array_init(&sync->uid_conflicts, 128); - i_array_init(&sync->new_msgs, 128); - i_array_init(&sync->copy_retry_indexes, 32); - - /* initialize message iteration on both workers */ - count = array_count(&guids); - sync->src_msg_iter = - dsync_brain_msg_iter_init(sync, brain->src_worker, - array_idx(&guids, 0), count); - sync->dest_msg_iter = - dsync_brain_msg_iter_init(sync, brain->dest_worker, - array_idx(&guids, 0), count); - - sync->guid_hash = hash_table_create(default_pool, pool, 10000, - strcase_hash, - (hash_cmp_callback_t *)strcasecmp); - sync->dest_msg_iter->save_guids = TRUE; - return sync; -} - -static void dsync_brain_msg_sync_deinit(struct dsync_brain_mailbox_sync **_sync) -{ - struct dsync_brain_mailbox_sync *sync = *_sync; - - *_sync = NULL; - - if (sync->src_msg_iter->iter != NULL) - (void)dsync_worker_msg_iter_deinit(&sync->src_msg_iter->iter); - if (sync->dest_msg_iter->iter != NULL) - (void)dsync_worker_msg_iter_deinit(&sync->dest_msg_iter->iter); - - hash_table_destroy(&sync->guid_hash); - array_free(&sync->uid_conflicts); - array_free(&sync->new_msgs); - array_free(&sync->copy_retry_indexes); - pool_unref(&sync->pool); -} - -static void dsync_brain_sync_existing_mailboxes(struct dsync_brain *brain) -{ - brain->mailbox_sync = dsync_brain_msg_sync_init(brain); - dsync_brain_msg_sync_more(brain->mailbox_sync); -} - -static int -dsync_brain_msg_sync_add_new_msg(struct dsync_brain_mailbox_sync *sync, - const struct dsync_mailbox *src_mailbox, - unsigned int msg_idx, - const struct dsync_message *msg) -{ - const struct dsync_brain_guid_instance *inst; - struct dsync_mailbox *const *inst_box; - struct dsync_msg_static_data data; - int ret; - - inst = hash_table_lookup(sync->guid_hash, msg->guid); - if (inst != NULL) { - /* we can save this by copying an existing message */ - dsync_worker_select_mailbox(sync->brain->dest_worker, - &src_mailbox->guid); - dsync_worker_set_next_result_tag(sync->brain->dest_worker, - msg_idx+1); - inst_box = array_idx(&sync->brain->src_mailbox_list->mailboxes, - inst->mailbox_idx); - dsync_worker_msg_copy(sync->brain->dest_worker, - &(*inst_box)->guid, inst->uid, msg); - sync->copy_results_left++; - } else { - dsync_worker_select_mailbox(sync->brain->src_worker, - &src_mailbox->guid); - ret = dsync_worker_msg_get(sync->brain->src_worker, - msg->uid, &data); - if (ret <= 0) { - if (ret == 0) { - /* mail got expunged during sync. - just skip this. */ - return 1; - } else { - dsync_brain_fail(sync->brain); - return -1; - } - } - dsync_worker_select_mailbox(sync->brain->dest_worker, - &src_mailbox->guid); - dsync_worker_msg_save(sync->brain->dest_worker, msg, &data); + for (; src < src_count; src++) { + brain_box = array_append_space(brain_boxes); + brain_box->box = *src_boxes[src]; + brain_box->src = src_boxes[src]; } - return dsync_worker_is_output_full(sync->brain->dest_worker) ? 0 : 1; -} - -static void -dsync_brain_msg_sync_add_new_msgs(struct dsync_brain_mailbox_sync *sync) -{ - struct dsync_mailbox *const *mailboxes, *mailbox; - const struct dsync_brain_new_msg *msgs; - unsigned int i, mailbox_count, msg_count; - - mailboxes = array_get(&sync->brain->src_mailbox_list->mailboxes, - &mailbox_count); - msgs = array_get(&sync->new_msgs, &msg_count); - for (i = sync->next_new_msg; i < msg_count; i++) { - mailbox = mailboxes[msgs[i].mailbox_idx]; - if (dsync_brain_msg_sync_add_new_msg(sync, mailbox, i, - msgs[i].msg) <= 0) { - /* failed / continue later */ - sync->next_new_msg = i + 1; - return; - } - } - - /* all messages sent */ - if (sync->copy_results_left == 0) { - sync->brain->state++; - dsync_brain_sync(sync->brain); + for (; dest < dest_count; dest++) { + brain_box = array_append_space(brain_boxes); + brain_box->box = *dest_boxes[dest]; + brain_box->dest = dest_boxes[dest]; } } -static void dsync_worker_copy_input(void *context) +static void dsync_brain_sync_msgs(struct dsync_brain *brain) { - struct dsync_brain_mailbox_sync *sync = context; - struct dsync_brain_guid_instance *inst; - const struct dsync_brain_new_msg *msgs; - unsigned int count; - uint32_t tag; - int result; - - msgs = array_get(&sync->new_msgs, &count); - while (dsync_worker_get_next_result(sync->brain->dest_worker, - &tag, &result)) { - if (tag == 0 || tag > count) { - i_error("Worker sent result with invalid tag %u", tag); - dsync_brain_fail(sync->brain); - return; - } - tag--; - if (sync->copy_results_left == 0) { - i_error("Worker sent unexpected result"); - dsync_brain_fail(sync->brain); - return; - } - sync->copy_results_left--; - if (result < 0) { - /* mark the guid instance invalid and try again later */ - inst = hash_table_lookup(sync->guid_hash, - msgs[tag].msg->guid); - inst->failed = TRUE; - array_append(&sync->copy_retry_indexes, &tag, 1); - } - } - if (sync->copy_results_left == 0) { - sync->brain->state++; - dsync_brain_sync(sync->brain); - } -} - -static void dsync_worker_new_msg_output(void *context) -{ - struct dsync_brain_mailbox_sync *sync = context; - - dsync_brain_msg_sync_add_new_msgs(sync); -} - -static void -dsync_brain_msg_sync_new_msgs(struct dsync_brain_mailbox_sync *sync) -{ - dsync_worker_set_input_callback(sync->brain->dest_worker, - dsync_worker_copy_input, sync); - dsync_worker_set_output_callback(sync->brain->dest_worker, - dsync_worker_new_msg_output, sync); - dsync_brain_msg_sync_add_new_msgs(sync); -} + ARRAY_TYPE(dsync_brain_mailbox) mailboxes; -static void -dsync_brain_msg_sync_retry_copies(struct dsync_brain_mailbox_sync *sync) -{ - const uint32_t *indexes; - struct dsync_mailbox *const *mailboxes, *mailbox; - const struct dsync_brain_new_msg *msgs; - unsigned int i, msg_idx, idx_count, msg_count, mailbox_count; - struct dsync_brain_guid_instance *inst; - const char *guid_str; - void *orig_key, *orig_value; - - /* first remove GUID instances that had failed. */ - msgs = array_get(&sync->new_msgs, &msg_count); - indexes = array_get(&sync->copy_retry_indexes, &idx_count); - for (i = 0; i < idx_count; i++) { - guid_str = msgs[indexes[i]].msg->guid; - if (hash_table_lookup_full(sync->guid_hash, guid_str, - &orig_key, &orig_value)) - inst = orig_value; - else - inst = NULL; - if (inst != NULL && inst->failed) { - inst = inst->next; - if (inst == NULL) - hash_table_remove(sync->guid_hash, guid_str); - else { - hash_table_update(sync->guid_hash, orig_key, - inst); - } - } - } - - /* try saving again. there probably weren't many of them, so don't - worry about filling output buffer. */ - mailboxes = array_get(&sync->brain->src_mailbox_list->mailboxes, - &mailbox_count); - for (i = 0; i < idx_count; i++) { - msg_idx = indexes[i]; - mailbox = mailboxes[msgs[msg_idx].mailbox_idx]; - (void)dsync_brain_msg_sync_add_new_msg(sync, mailbox, msg_idx, - msgs[msg_idx].msg); - } - - /* if we copied anything, we'll again have to wait for the results */ - array_clear(&sync->copy_retry_indexes); - dsync_worker_set_output_callback(sync->brain->dest_worker, NULL, NULL); - - if (sync->copy_results_left == 0) { - dsync_worker_set_input_callback(sync->brain->dest_worker, - NULL, NULL); - sync->brain->state++; - dsync_brain_sync(sync->brain); - } else { - /* temporarily move back the state. once copies have returned - success/failures, we'll get back to this function and see - if we need to retry again */ - sync->brain->state--; - } + t_array_init(&mailboxes, 128); + dsync_brain_get_changed_mailboxes(brain, &mailboxes, + (brain->flags & DSYNC_BRAIN_FLAG_FULL_SYNC) != 0); + brain->mailbox_sync = dsync_brain_msg_sync_init(brain, &mailboxes); } static void dsync_brain_msg_sync_update_mailbox(struct dsync_brain *brain) { - struct dsync_mailbox *const *mailboxes; + const struct dsync_brain_mailbox *mailboxes; unsigned int i, count; - mailboxes = array_get(&brain->src_mailbox_list->mailboxes, &count); - for (i = 0; i < count; i++) - dsync_worker_update_mailbox(brain->dest_worker, mailboxes[i]); -} - -static void -dsync_brain_msg_sync_resolve_uid_conflicts(struct dsync_brain_mailbox_sync *sync) -{ - const struct dsync_brain_uid_conflict *conflicts; - struct dsync_mailbox *const *mailboxes, *mailbox; - unsigned int i, count, mailbox_count; - - mailboxes = array_get(&sync->brain->src_mailbox_list->mailboxes, - &mailbox_count); - conflicts = array_get(&sync->uid_conflicts, &count); + mailboxes = array_get(&brain->mailbox_sync->mailboxes, &count); for (i = 0; i < count; i++) { - mailbox = mailboxes[conflicts[i].mailbox_idx]; - dsync_worker_select_mailbox(sync->brain->dest_worker, - &mailbox->guid); - dsync_worker_msg_update_uid(sync->brain->dest_worker, - conflicts[i].uid); + dsync_worker_update_mailbox(brain->src_worker, + &mailboxes[i].box); + dsync_worker_update_mailbox(brain->dest_worker, + &mailboxes[i].box); } } @@ -755,9 +276,10 @@ dsync_worker_mailbox_input(brain->dest_mailbox_list); break; case DSYNC_STATE_CREATE_MAILBOXES: - if (array_count(&brain->src_mailbox_list->mailboxes) == 0) { + if (array_count(&brain->src_mailbox_list->mailboxes) == 0 && + array_count(&brain->dest_mailbox_list->mailboxes) == 0) { /* no mailboxes */ - i_error("No source mailboxes"); + i_error("No mailboxes"); dsync_brain_fail(brain); } @@ -766,14 +288,8 @@ dsync_brain_create_missing_mailboxes(brain); brain->state++; /* fall through */ - case DSYNC_STATE_SYNC_EXISTING_MSGS: - dsync_brain_sync_existing_mailboxes(brain); - break; - case DSYNC_STATE_SYNC_NEW_MSGS: - dsync_brain_msg_sync_new_msgs(brain->mailbox_sync); - break; - case DSYNC_STATE_SYNC_RETRY_COPIES: - dsync_brain_msg_sync_retry_copies(brain->mailbox_sync); + case DSYNC_STATE_SYNC_MSGS: + dsync_brain_sync_msgs(brain); break; case DSYNC_STATE_SYNC_UPDATE_MAILBOX: dsync_brain_msg_sync_update_mailbox(brain); @@ -786,6 +302,7 @@ brain->state++; /* fall through */ case DSYNC_STATE_SYNC_FLUSH: + /* FIXME: retrieve worker failures and set brain failure */ dsync_worker_set_output_callback(brain->dest_worker, dsync_worker_flush_callback, brain);