bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "lib.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "array.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "hash.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mail-cache-private.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mail-namespace.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "mail-storage-private.h"
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen#include "dsync-ibc.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "dsync-mailbox-tree.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "dsync-mailbox-import.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "dsync-mailbox-export.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "dsync-transaction-log-scan.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen#include "dsync-brain-private.h"
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainenns_mailbox_try_alloc(struct dsync_brain *brain, struct mail_namespace *ns,
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen const guid_128_t guid, struct mailbox **box_r,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen const char **errstr_r, enum mail_error *error_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen enum mailbox_flags flags = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mailbox_existence existence;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen if (brain->backup_send) {
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen /* make sure mailbox isn't modified */
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen flags |= MAILBOX_FLAG_READONLY;
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen }
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen
de3175adb4094086dc8ba13132a39567f9c42e54Timo Sirainen box = mailbox_alloc_guid(ns->list, guid, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ret = mailbox_exists(box, FALSE, &existence);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (ret < 0) {
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi *errstr_r = mailbox_get_last_internal_error(box, error_r);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (existence != MAILBOX_EXISTENCE_SELECT) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen *errstr_r = existence == MAILBOX_EXISTENCE_NONE ?
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen "Mailbox was already deleted" :
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen "Mailbox is no longer selectable";
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *box_r = box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenint dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen struct mailbox **box_r, const char **errstr_r,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen enum mail_error *error_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mail_namespace *ns;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *box_r = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
3c73d884362b72c86753939551c94f8baa5702f8Timo Sirainen if (!dsync_brain_want_namespace(brain, ns))
3c73d884362b72c86753939551c94f8baa5702f8Timo Sirainen continue;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if ((ret = ns_mailbox_try_alloc(brain, ns, guid, box_r,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen errstr_r, error_r)) != 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainenstatic void
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainendsync_mailbox_cache_field_dup(ARRAY_TYPE(mailbox_cache_field) *dest,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen const ARRAY_TYPE(mailbox_cache_field) *src,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen pool_t pool)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen{
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen const struct mailbox_cache_field *src_field;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen struct mailbox_cache_field *dest_field;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen p_array_init(dest, pool, array_count(src));
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen array_foreach(src, src_field) {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dest_field = array_append_space(dest);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dest_field->name = p_strdup(pool, src_field->name);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dest_field->decision = src_field->decision;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dest_field->last_used = src_field->last_used;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen }
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen}
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic const struct dsync_mailbox_state *
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_mailbox_state_find(struct dsync_brain *brain,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const guid_128_t mailbox_guid)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen const uint8_t *guid_p;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen guid_p = mailbox_guid;
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen return hash_table_lookup(brain->mailbox_states, guid_p);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_mailbox_state_remove(struct dsync_brain *brain,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const guid_128_t mailbox_guid)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen const uint8_t *guid_p;
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen guid_p = mailbox_guid;
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen if (hash_table_lookup(brain->mailbox_states, guid_p) != NULL)
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen hash_table_remove(brain->mailbox_states, guid_p);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainenvoid dsync_brain_sync_init_box_states(struct dsync_brain *brain)
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen{
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen if (brain->backup_send) {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen /* we have an exporter, but no importer. */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES;
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen brain->box_recv_state = brain->mail_requests ?
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen DSYNC_BOX_STATE_MAIL_REQUESTS :
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen DSYNC_BOX_STATE_RECV_LAST_COMMON;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen } else if (brain->backup_recv) {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen /* we have an importer, but no exporter */
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen brain->box_send_state = brain->mail_requests ?
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen DSYNC_BOX_STATE_MAIL_REQUESTS :
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen DSYNC_BOX_STATE_DONE;
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen } else {
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES;
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen }
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen}
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainenstatic void
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_brain_sync_mailbox_init(struct dsync_brain *brain,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box,
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock *lock,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *local_dsync_box,
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen bool wait_for_remote_box)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox_state *state;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box_importer == NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box_exporter == NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(box->synced);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->box = box;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen brain->box_lock = lock;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->pre_box_state = brain->state;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen if (wait_for_remote_box) {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen brain->box_send_state = DSYNC_BOX_STATE_MAILBOX;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen brain->box_recv_state = DSYNC_BOX_STATE_MAILBOX;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen } else {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen dsync_brain_sync_init_box_states(brain);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->local_dsync_box = *local_dsync_box;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen if (brain->dsync_box_pool != NULL)
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen p_clear(brain->dsync_box_pool);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen else {
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen brain->dsync_box_pool =
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen pool_alloconly_create(MEMPOOL_GROWING"dsync brain box pool", 2048);
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen }
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dsync_mailbox_cache_field_dup(&brain->local_dsync_box.cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen &local_dsync_box->cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen brain->dsync_box_pool);
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&brain->remote_dsync_box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state = dsync_mailbox_state_find(brain, local_dsync_box->mailbox_guid);
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen if (state != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->mailbox_state = *state;
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen else {
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&brain->mailbox_state);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen memcpy(brain->mailbox_state.mailbox_guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen local_dsync_box->mailbox_guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen sizeof(brain->mailbox_state.mailbox_guid));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->mailbox_state.last_uidvalidity =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen local_dsync_box->uid_validity;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenstatic void
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainendsync_brain_sync_mailbox_init_remote(struct dsync_brain *brain,
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen const struct dsync_mailbox *remote_dsync_box)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum dsync_mailbox_import_flags import_flags = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox_state *state;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen uint32_t last_common_uid;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen uint64_t last_common_modseq, last_common_pvt_modseq;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box_importer == NULL);
c7be65f5adbc2990fbe6eeffb6df5054a8a49d9dTimo Sirainen i_assert(brain->log_scan != NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(memcmp(brain->local_dsync_box.mailbox_guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_dsync_box->mailbox_guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen sizeof(remote_dsync_box->mailbox_guid)) == 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->remote_dsync_box = *remote_dsync_box;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dsync_mailbox_cache_field_dup(&brain->remote_dsync_box.cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen &remote_dsync_box->cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen brain->dsync_box_pool);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state = dsync_mailbox_state_find(brain, remote_dsync_box->mailbox_guid);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (state != NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen last_common_uid = state->last_common_uid;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen last_common_modseq = state->last_common_modseq;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen last_common_pvt_modseq = state->last_common_pvt_modseq;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen last_common_uid = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen last_common_modseq = 0;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen last_common_pvt_modseq = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
887a9fbbb2ca6afd53365ba2ccae0ef8728d6948Timo Sirainen if (brain->mail_requests)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_WANT_MAIL_REQUESTS;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (brain->master_brain)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MASTER_BRAIN;
36723cf206a7b64b9d972ab0719bbfaacc9316faTimo Sirainen if (brain->backup_recv && !brain->no_backup_overwrite)
efeb13303798b47d2c4295468d233c1bcfd79c94Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_REVERT_LOCAL_CHANGES;
307ec6c2c319e3335ddb1a7aca2d2884fe17fae0Timo Sirainen if (brain->debug)
307ec6c2c319e3335ddb1a7aca2d2884fe17fae0Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_DEBUG;
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen if (brain->local_dsync_box.have_save_guids &&
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen (remote_dsync_box->have_save_guids ||
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen (brain->backup_recv && remote_dsync_box->have_guids)))
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS;
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen if (brain->local_dsync_box.have_only_guid128 ||
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen remote_dsync_box->have_only_guid128)
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128;
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen if (brain->no_notify)
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_NO_NOTIFY;
afd6d387ea65843b59fb6051fb567719d2a5279cAki Tuomi if (brain->empty_hdr_workaround)
afd6d387ea65843b59fb6051fb567719d2a5279cAki Tuomi import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_EMPTY_HDR_WORKAROUND;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen brain->box_importer = brain->backup_send ? NULL :
70df8f39fb3db7c49b18c855178f8172176a037aTimo Sirainen dsync_mailbox_import_init(brain->box, brain->virtual_all_box,
70df8f39fb3db7c49b18c855178f8172176a037aTimo Sirainen brain->log_scan,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen last_common_uid, last_common_modseq,
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen last_common_pvt_modseq,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_dsync_box->uid_next,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_dsync_box->first_recent_uid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_dsync_box->highest_modseq,
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen remote_dsync_box->highest_pvt_modseq,
3561c7bb472a78af74d755219cc0fc71c85ff5c2Timo Sirainen brain->sync_since_timestamp,
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi brain->sync_until_timestamp,
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen brain->sync_max_size,
2e652d2651b2800f99a17dcb3014a009fe4660d3Timo Sirainen brain->sync_flag,
a76faea3eb26c4cd67886fbe02c604f74d54be8cTimo Sirainen brain->import_commit_msgs_interval,
69a71891361b2b27ff68ed84b29278486628464aAki Tuomi import_flags, brain->hdr_hash_version,
69a71891361b2b27ff68ed84b29278486628464aAki Tuomi brain->hashed_headers);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainenint dsync_brain_sync_mailbox_open(struct dsync_brain *brain,
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen const struct dsync_mailbox *remote_dsync_box)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen{
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen struct mailbox_status status;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen enum dsync_mailbox_exporter_flags exporter_flags = 0;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen uint32_t last_common_uid, highest_wanted_uid;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen uint64_t last_common_modseq, last_common_pvt_modseq;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen const char *desync_reason = "";
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen bool pvt_too_old;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen int ret;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen i_assert(brain->log_scan == NULL);
237a6211c7fc4d6dbb58dd0467da6dba1b8f21f6Timo Sirainen i_assert(brain->box_exporter == NULL);
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen last_common_uid = brain->mailbox_state.last_common_uid;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen last_common_modseq = brain->mailbox_state.last_common_modseq;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen last_common_pvt_modseq = brain->mailbox_state.last_common_pvt_modseq;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen highest_wanted_uid = last_common_uid == 0 ?
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen (uint32_t)-1 : last_common_uid;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen ret = dsync_transaction_log_scan_init(brain->box->view,
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen brain->box->view_pvt,
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen highest_wanted_uid,
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen last_common_modseq,
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen last_common_pvt_modseq,
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen &brain->log_scan, &pvt_too_old);
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen if (ret < 0) {
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen i_error("Failed to read transaction log for mailbox %s",
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen mailbox_get_vname(brain->box));
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen brain->failed = TRUE;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen return -1;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen }
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen mailbox_get_open_status(brain->box, STATUS_UIDNEXT |
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen STATUS_HIGHESTMODSEQ |
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen STATUS_HIGHESTPVTMODSEQ, &status);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if (ret == 0) {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if (pvt_too_old) {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen desync_reason = t_strdup_printf(
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi "Private modseq %"PRIu64" no longer in transaction log "
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen "(highest=%"PRIu64", last_common_uid=%u, nextuid=%u)",
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi last_common_pvt_modseq,
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen status.highest_pvt_modseq, last_common_uid,
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen status.uidnext);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen } else {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen desync_reason = t_strdup_printf(
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi "Modseq %"PRIu64" no longer in transaction log "
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen "(highest=%"PRIu64", last_common_uid=%u, nextuid=%u)",
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi last_common_modseq,
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen status.highest_modseq, last_common_uid,
328ac493fb40b35a6e1d618bd87ffa0e02f4764fTimo Sirainen status.uidnext);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen }
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen }
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen if (last_common_uid != 0) {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen /* if last_common_* is higher than our current ones it means
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen that the incremental sync state is stale and we need to do
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen a full resync */
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen if (status.uidnext < last_common_uid) {
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen desync_reason = t_strdup_printf("uidnext %u < %u",
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen status.uidnext, last_common_uid);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen ret = 0;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen } else if (status.highest_modseq < last_common_modseq) {
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi desync_reason = t_strdup_printf("highest_modseq %"PRIu64" < %"PRIu64,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi status.highest_modseq, last_common_modseq);
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen ret = 0;
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen } else if (status.highest_pvt_modseq < last_common_pvt_modseq) {
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi desync_reason = t_strdup_printf("highest_pvt_modseq %"PRIu64" < %"PRIu64,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi status.highest_pvt_modseq, last_common_pvt_modseq);
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen ret = 0;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen }
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen }
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen if (ret == 0) {
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen i_warning("Failed to do incremental sync for mailbox %s, "
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen "retry with a full sync (%s)",
70058d29cf8c77501741ddbc39178cfc87ca459eTimo Sirainen mailbox_get_vname(brain->box), desync_reason);
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, t_strdup_printf(
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen "Incremental sync failed: %s", desync_reason));
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen brain->require_full_resync = TRUE;
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen return 0;
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen }
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen if (!brain->mail_requests)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_AUTO_EXPORT_MAILS;
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen if (remote_dsync_box->have_save_guids &&
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen (brain->local_dsync_box.have_save_guids ||
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen (brain->backup_send && brain->local_dsync_box.have_guids)))
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS;
d519a0449d0e536a32db93305516fdbd7db6773dTimo Sirainen if (brain->no_mail_prefetch)
d519a0449d0e536a32db93305516fdbd7db6773dTimo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MINIMAL_DMAIL_FILL;
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi if (brain->sync_since_timestamp > 0 ||
ee8294dbc7bb549557f6ba1264d66b55fbef69b6Aki Tuomi brain->sync_until_timestamp > 0)
3561c7bb472a78af74d755219cc0fc71c85ff5c2Timo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS;
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen if (brain->sync_max_size > 0)
ae949831f1f668b5501b4b125e7f7b1767fb109bTimo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_VSIZES;
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen if (remote_dsync_box->messages_count == 0) {
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen /* remote mailbox is empty - we don't really need to export
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen header hashes since they're not going to match anything
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen anyway. */
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_NO_HDR_HASHES;
03af8e5325a7b4fec36414ac35949457bc426c0bTimo Sirainen }
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen brain->box_exporter = brain->backup_recv ? NULL :
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen dsync_mailbox_export_init(brain->box, brain->log_scan,
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen last_common_uid,
f3c24c2c92802cb773315eba1132254932d8709bTimo Sirainen exporter_flags,
69a71891361b2b27ff68ed84b29278486628464aAki Tuomi brain->hdr_hash_version,
69a71891361b2b27ff68ed84b29278486628464aAki Tuomi brain->hashed_headers);
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen dsync_brain_sync_mailbox_init_remote(brain, remote_dsync_box);
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen return 1;
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen}
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid dsync_brain_sync_mailbox_deinit(struct dsync_brain *brain)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen enum mail_error error;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box != NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c307328f59c963eba21091ecd36c9435d42b47d8Timo Sirainen array_append(&brain->remote_mailbox_states, &brain->mailbox_state, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (brain->box_exporter != NULL) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen const char *errstr;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
f43ce62fa945f597e8a48e09c53d46dcc95445d4Timo Sirainen i_assert(brain->failed || brain->require_full_resync ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_CHANGED);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (dsync_mailbox_export_deinit(&brain->box_exporter,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen &errstr, &error) < 0)
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen i_error("Mailbox export failed: %s", errstr);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (brain->box_importer != NULL) {
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen uint32_t last_common_uid, last_messages_count;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen uint64_t last_common_modseq, last_common_pvt_modseq;
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen const char *changes_during_sync;
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen bool require_full_resync;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->failed);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (void)dsync_mailbox_import_deinit(&brain->box_importer,
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen FALSE,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen &last_common_uid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen &last_common_modseq,
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen &last_common_pvt_modseq,
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen &last_messages_count,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen &changes_during_sync,
805d7834412465268486c50711962407ad13fbf6Timo Sirainen &require_full_resync,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen &brain->mail_error);
805d7834412465268486c50711962407ad13fbf6Timo Sirainen if (require_full_resync)
805d7834412465268486c50711962407ad13fbf6Timo Sirainen brain->require_full_resync = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (brain->log_scan != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_transaction_log_scan_deinit(&brain->log_scan);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&brain->box_lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&brain->box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->state = brain->pre_box_state;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic int dsync_box_get(struct mailbox *box, struct dsync_mailbox *dsync_box_r,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen enum mail_error *error_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const enum mailbox_status_items status_items =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_MESSAGES |
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen STATUS_FIRST_RECENT_UID | STATUS_HIGHESTMODSEQ |
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen STATUS_HIGHESTPVTMODSEQ;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const enum mailbox_metadata_items metadata_items =
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen MAILBOX_METADATA_CACHE_FIELDS | MAILBOX_METADATA_GUID;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_status status;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_metadata metadata;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *errstr;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen enum mail_error error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* get metadata first, since it may autocreate the mailbox */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_get_metadata(box, metadata_items, &metadata) < 0 ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_get_status(box, status_items, &status) < 0) {
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi errstr = mailbox_get_last_internal_error(box, &error);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (error == MAIL_ERROR_NOTFOUND ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen error == MAIL_ERROR_NOTPOSSIBLE) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* Mailbox isn't selectable, try the next one. We
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen should have already caught \Noselect mailboxes, but
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen check them anyway here. The NOTPOSSIBLE check is
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mainly for invalid mbox files. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Failed to access mailbox %s: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_get_vname(box), errstr);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen *error_r = error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(status.uidvalidity != 0 || status.messages == 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(dsync_box_r);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen memcpy(dsync_box_r->mailbox_guid, metadata.guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen sizeof(dsync_box_r->mailbox_guid));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_box_r->uid_validity = status.uidvalidity;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_box_r->uid_next = status.uidnext;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_box_r->messages_count = status.messages;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_box_r->first_recent_uid = status.first_recent_uid;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_box_r->highest_modseq = status.highest_modseq;
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen dsync_box_r->highest_pvt_modseq = status.highest_pvt_modseq;
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen dsync_mailbox_cache_field_dup(&dsync_box_r->cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen metadata.cache_fields,
9f240e2ce97176146b63506a8ee04034f712cf45Timo Sirainen pool_datastack_create());
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen dsync_box_r->have_guids = status.have_guids;
14f6fe5d6c4834f273ca573c23c0659a93123363Timo Sirainen dsync_box_r->have_save_guids = status.have_save_guids;
cce2c665bb24537bb691f6cad6a36f8080e4a552Timo Sirainen dsync_box_r->have_only_guid128 = status.have_only_guid128;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_brain_has_mailbox_state_changed(struct dsync_brain *brain,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *dsync_box)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox_state *state;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_STATE)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state = dsync_mailbox_state_find(brain, dsync_box->mailbox_guid);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return state == NULL ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state->last_uidvalidity != dsync_box->uid_validity ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state->last_common_uid+1 != dsync_box->uid_next ||
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen state->last_common_modseq != dsync_box->highest_modseq ||
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen state->last_common_pvt_modseq != dsync_box->highest_pvt_modseq ||
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen state->last_messages_count != dsync_box->messages_count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_brain_try_next_mailbox(struct dsync_brain *brain, struct mailbox **box_r,
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock **lock_r,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct dsync_mailbox *dsync_box_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen enum mailbox_flags flags = 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct dsync_mailbox dsync_box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock *lock = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct dsync_mailbox_node *node;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *vname = NULL;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen enum mail_error error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen bool synced = FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
fbd671a3f51a5f92535923fcaf05fed1e5712ae4Timo Sirainen *box_r = NULL;
fbd671a3f51a5f92535923fcaf05fed1e5712ae4Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen while (dsync_mailbox_tree_iter_next(brain->local_tree_iter, &vname, &node)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (node->existence == DSYNC_MAILBOX_NODE_EXISTS &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen !guid_128_is_empty(node->mailbox_guid))
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen vname = NULL;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (vname == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* no more mailboxes */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_mailbox_tree_iter_deinit(&brain->local_tree_iter);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen if (brain->backup_send) {
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen /* make sure mailbox isn't modified */
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen flags |= MAILBOX_FLAG_READONLY;
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen }
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen box = mailbox_alloc(node->ns->list, vname, flags);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (;;) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if ((ret = dsync_box_get(box, &dsync_box, &error)) <= 0) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if (ret < 0) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen brain->mail_error = error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->failed = TRUE;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* if mailbox's last_common_* state equals the current state,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen we can skip the mailbox */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (!dsync_brain_has_mailbox_state_changed(brain, &dsync_box)) {
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen if (brain->debug) {
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen i_debug("brain %c: Skipping mailbox %s with unchanged state "
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi "uidvalidity=%u uidnext=%u highestmodseq=%"PRIu64" highestpvtmodseq=%"PRIu64" messages=%u",
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen brain->master_brain ? 'M' : 'S',
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen guid_128_to_string(dsync_box.mailbox_guid),
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen dsync_box.uid_validity,
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen dsync_box.uid_next,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi dsync_box.highest_modseq,
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi dsync_box.highest_pvt_modseq,
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen dsync_box.messages_count);
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (synced) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* ok, the mailbox really changed */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen break;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* mailbox appears to have changed. do a full sync here and get the
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen state again. Lock before syncing. */
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen if (dsync_mailbox_lock(brain, box, &lock) < 0) {
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen brain->failed = TRUE;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen mailbox_free(&box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen return -1;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Can't sync mailbox %s: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, &brain->mail_error));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return -1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen synced = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *box_r = box;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen *lock_r = lock;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen *dsync_box_r = dsync_box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return 1;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic bool
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_brain_next_mailbox(struct dsync_brain *brain, struct mailbox **box_r,
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock **lock_r,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct dsync_mailbox *dsync_box_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen if (brain->no_mail_sync)
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen return FALSE;
a0ebe2a2271759599686f3480aee6a6fe445d16eTimo Sirainen
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen while ((ret = dsync_brain_try_next_mailbox(brain, box_r, lock_r, dsync_box_r)) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return ret > 0;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenvoid dsync_brain_master_send_mailbox(struct dsync_brain *brain)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct dsync_mailbox dsync_box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock *lock;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->master_brain);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box == NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen if (!dsync_brain_next_mailbox(brain, &box, &lock, &dsync_box)) {
24bd831901b8fd59718e353b36eaef6a950f09a2Timo Sirainen brain->state = DSYNC_STATE_FINISH;
b8e6e314eb2f9f1fc8ce2999034321bfeb7a2269Timo Sirainen dsync_ibc_send_end_of_list(brain->ibc, DSYNC_IBC_EOL_MAILBOX);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* start exporting this mailbox (wait for remote to start importing) */
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen dsync_ibc_send_mailbox(brain->ibc, &dsync_box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen dsync_brain_sync_mailbox_init(brain, box, lock, &dsync_box, TRUE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->state = DSYNC_STATE_SYNC_MAILS;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainenbool dsync_boxes_need_sync(struct dsync_brain *brain,
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen const struct dsync_mailbox *box1,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *box2)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen if (brain->no_mail_sync)
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen return FALSE;
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_CHANGED)
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return box1->highest_modseq != box2->highest_modseq ||
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen box1->highest_pvt_modseq != box2->highest_pvt_modseq ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen box1->messages_count != box2->messages_count ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen box1->uid_next != box2->uid_next ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen box1->uid_validity != box2->uid_validity ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen box1->first_recent_uid != box2->first_recent_uid;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmailbox_cache_field_name_cmp(const struct mailbox_cache_field *f1,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_cache_field *f2)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return strcmp(f1->name, f2->name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainendsync_cache_fields_update(const struct dsync_mailbox *local_box,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *remote_box,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen struct mailbox *box,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_update *update)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ARRAY_TYPE(mailbox_cache_field) local_sorted, remote_sorted, changes;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_cache_field *local_fields, *remote_fields;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int li, ri, local_count, remote_count;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen time_t drop_older_timestamp;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (array_count(&remote_box->cache_fields) == 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* remote has no cached fields. there's nothing to update. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen t_array_init(&local_sorted, array_count(&local_box->cache_fields));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen t_array_init(&remote_sorted, array_count(&remote_box->cache_fields));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_append_array(&local_sorted, &local_box->cache_fields);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_append_array(&remote_sorted, &remote_box->cache_fields);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_sort(&local_sorted, mailbox_cache_field_name_cmp);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_sort(&remote_sorted, mailbox_cache_field_name_cmp);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (array_count(&local_sorted) == 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* local has no cached fields. set them to same as remote. */
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&remote_sorted);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen update->cache_updates = array_idx(&remote_sorted, 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* figure out what to change */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen local_fields = array_get(&local_sorted, &local_count);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_fields = array_get(&remote_sorted, &remote_count);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen t_array_init(&changes, local_count + remote_count);
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen drop_older_timestamp = ioloop_time -
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen box->index->optimization_set.cache.unaccessed_field_drop_secs;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (li = ri = 0; li < local_count || ri < remote_count; ) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ret = li == local_count ? 1 :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ri == remote_count ? -1 :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen strcmp(local_fields[li].name, remote_fields[ri].name);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (ret == 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* field exists in both local and remote */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_cache_field *lf = &local_fields[li];
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct mailbox_cache_field *rf = &remote_fields[ri];
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (lf->last_used > rf->last_used ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (lf->last_used == rf->last_used &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen lf->decision > rf->decision)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* use local decision and timestamp */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_append(&changes, rf, 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen li++; ri++;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else if (ret < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* remote field doesn't exist */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen li++;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* local field doesn't exist */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (remote_fields[ri].last_used < drop_older_timestamp) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* field hasn't be used for a long time, remote
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen will probably drop this soon as well */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen } else {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen array_append(&changes, &remote_fields[ri], 1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen ri++;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(li == local_count && ri == remote_count);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (array_count(&changes) > 0) {
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&changes);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen update->cache_updates = array_idx(&changes, 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainenbool dsync_brain_mailbox_update_pre(struct dsync_brain *brain,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *local_box,
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen const struct dsync_mailbox *remote_box,
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen const char **reason_r)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox_update update;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox_state *state;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen bool ret = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen *reason_r = NULL;
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (local_box->uid_validity != remote_box->uid_validity) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* Keep the UIDVALIDITY for the mailbox that has more
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen messages. If they equal, use the higher UIDVALIDITY. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (remote_box->messages_count > local_box->messages_count ||
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (remote_box->messages_count == local_box->messages_count &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen remote_box->uid_validity > local_box->uid_validity))
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen update.uid_validity = remote_box->uid_validity;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen state = dsync_mailbox_state_find(brain, local_box->mailbox_guid);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (state != NULL && state->last_common_uid > 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* we can't continue syncing this mailbox in this
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen session, because the other side already started
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen sending mailbox changes, but not for all mails. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen dsync_mailbox_state_remove(brain, local_box->mailbox_guid);
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen *reason_r = "UIDVALIDITY changed during a stateful sync, need to restart";
b62495f818944c701e22b7a9a31d81d0c2f4543dAki Tuomi brain->failed = TRUE;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen ret = FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dsync_cache_fields_update(local_box, remote_box, box, &update);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (update.uid_validity == 0 &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen update.cache_updates == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* no changes */
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen return ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_update(box, &update) < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Couldn't update mailbox %s metadata: %s",
63f01d5e4c9efe985fad63d5851dd1c5c153affaTimo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, &brain->mail_error));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen return ret;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainenstatic void
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainendsync_brain_slave_send_mailbox_lost(struct dsync_brain *brain,
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi const struct dsync_mailbox *dsync_box,
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi bool ignore)
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen{
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen struct dsync_mailbox delete_box;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen if (brain->debug) {
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen i_debug("brain %c: We don't have mailbox %s",
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen brain->master_brain ? 'M' : 'S',
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen guid_128_to_string(dsync_box->mailbox_guid));
9ed42a54bed303c68106e59b2072e98930048177Timo Sirainen }
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&delete_box);
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen memcpy(delete_box.mailbox_guid, dsync_box->mailbox_guid,
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen sizeof(delete_box.mailbox_guid));
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen t_array_init(&delete_box.cache_fields, 0);
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi if (ignore)
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi delete_box.mailbox_ignore = TRUE;
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi else
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi delete_box.mailbox_lost = TRUE;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen dsync_ibc_send_mailbox(brain->ibc, &delete_box);
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen}
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenbool dsync_brain_slave_recv_mailbox(struct dsync_brain *brain)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen{
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct dsync_mailbox *dsync_box;
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen struct dsync_mailbox local_dsync_box;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mailbox *box;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen struct file_lock *lock;
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen const char *errstr, *resync_reason;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen enum mail_error error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen int ret;
40440c0fee87be994ba7eb60fc3512a9355708aaTimo Sirainen bool resync;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(!brain->master_brain);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(brain->box == NULL);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
a85473f7c11c8734bdee9c2cbe4b767f144a18aaTimo Sirainen if ((ret = dsync_ibc_recv_mailbox(brain->ibc, &dsync_box)) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return FALSE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (ret < 0) {
24bd831901b8fd59718e353b36eaef6a950f09a2Timo Sirainen brain->state = DSYNC_STATE_FINISH;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen if (dsync_brain_mailbox_alloc(brain, dsync_box->mailbox_guid,
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen &box, &errstr, &error) < 0) {
ec047a9c54a02338e85fb1767120b0923f6d4148Timo Sirainen i_error("Couldn't allocate mailbox GUID %s: %s",
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen guid_128_to_string(dsync_box->mailbox_guid), errstr);
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen brain->mail_error = error;
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen brain->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (box == NULL) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* mailbox was probably deleted/renamed during sync */
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen if (brain->backup_send && brain->no_backup_overwrite) {
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen if (brain->debug) {
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen i_debug("brain %c: Ignore nonexistent "
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen "mailbox GUID %s with -1 sync",
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen brain->master_brain ? 'M' : 'S',
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen guid_128_to_string(dsync_box->mailbox_guid));
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen }
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi dsync_brain_slave_send_mailbox_lost(brain, dsync_box, TRUE);
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen return TRUE;
16cd2c1b487b1fb63f3081761e0d1110d61137a9Timo Sirainen }
e0c10ab25f82f3b5b099de5d84ece39efd18bc6aTimo Sirainen //FIXME: verify this from log, and if not log an error.
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, t_strdup_printf(
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen "Mailbox GUID %s was lost",
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen guid_128_to_string(dsync_box->mailbox_guid)));
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi dsync_brain_slave_send_mailbox_lost(brain, dsync_box, FALSE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen /* Lock before syncing */
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen if (dsync_mailbox_lock(brain, box, &lock) < 0) {
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen mailbox_free(&box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen brain->failed = TRUE;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen return TRUE;
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Can't sync mailbox %s: %s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, &brain->mail_error));
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen if ((ret = dsync_box_get(box, &local_dsync_box, &error)) <= 0) {
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (ret < 0) {
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainen brain->mail_error = error;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->failed = TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* another process just deleted this mailbox? */
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen if (brain->debug) {
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen i_debug("brain %c: Skipping lost mailbox %s",
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen brain->master_brain ? 'M' : 'S',
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen guid_128_to_string(dsync_box->mailbox_guid));
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen }
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi dsync_brain_slave_send_mailbox_lost(brain, dsync_box, FALSE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(local_dsync_box.uid_validity != 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_assert(memcmp(dsync_box->mailbox_guid, local_dsync_box.mailbox_guid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen sizeof(dsync_box->mailbox_guid)) == 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen resync = !dsync_brain_mailbox_update_pre(brain, box, &local_dsync_box,
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_box, &resync_reason);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
f48fdb57185ca68e8c079e174f3e04da36646880Timo Sirainen if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box)) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* no fields appear to have changed, skip this mailbox */
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen if (brain->debug) {
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen i_debug("brain %c: Skipping unchanged mailbox %s",
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen brain->master_brain ? 'M' : 'S',
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen guid_128_to_string(dsync_box->mailbox_guid));
e475db821baf0c4680dec4441d033697ecebfe06Timo Sirainen }
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen dsync_ibc_send_mailbox(brain->ibc, &local_dsync_box);
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen file_lock_free(&lock);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mailbox_free(&box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* start export/import */
c864fdd520b0c3f10a4b9bc5373368f4ae8faaffTimo Sirainen dsync_brain_sync_mailbox_init(brain, box, lock, &local_dsync_box, FALSE);
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen if ((ret = dsync_brain_sync_mailbox_open(brain, dsync_box)) < 0)
979d89c147520f2934c14c31aeb9310fd2d62a46Timo Sirainen return TRUE;
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen if (resync)
4f7951e71128c120d8a502d6406cc603fcc8eb0bTimo Sirainen dsync_brain_set_changes_during_sync(brain, resync_reason);
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen if (ret == 0 || resync) {
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen brain->require_full_resync = TRUE;
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen dsync_brain_sync_mailbox_deinit(brain);
280bc7d8b07490dfa5cf0fc20aee8e9e2d15aa99Aki Tuomi dsync_brain_slave_send_mailbox_lost(brain, dsync_box, FALSE);
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen return TRUE;
7d315281ae13a66e13da2b1ad006bdb883018278Timo Sirainen }
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen
464e82904c6670bd6c96b8793ceb294d776d6f44Timo Sirainen dsync_ibc_send_mailbox(brain->ibc, &local_dsync_box);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen brain->state = DSYNC_STATE_SYNC_MAILS;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return TRUE;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen}