From 34421746925a2e1850549fa0fa07ddeeb1a271e2 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sat, 16 Feb 2013 17:17:14 +0200 Subject: [PATCH] dsync: Merge last-common-* values from both local and remote when they differ. --- src/doveadm/dsync/dsync-brain-mails.c | 21 +++++++++++++++++---- src/doveadm/dsync/dsync-ibc-stream.c | 7 ++++++- src/doveadm/dsync/dsync-mailbox-state.h | 1 + 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/doveadm/dsync/dsync-brain-mails.c b/src/doveadm/dsync/dsync-brain-mails.c index 24346566f8..87e5069e0d 100644 --- a/src/doveadm/dsync/dsync-brain-mails.c +++ b/src/doveadm/dsync/dsync-brain-mails.c @@ -140,7 +140,6 @@ static bool dsync_brain_send_mail_request(struct dsync_brain *brain) static void dsync_brain_sync_half_finished(struct dsync_brain *brain) { struct dsync_mailbox_state state; - bool changes_during_sync; const char *error; if (brain->box_recv_state < DSYNC_BOX_STATE_RECV_LAST_COMMON || @@ -174,13 +173,14 @@ static void dsync_brain_sync_half_finished(struct dsync_brain *brain) &state.last_common_uid, &state.last_common_modseq, &state.last_common_pvt_modseq, - &changes_during_sync) < 0) { + &state.changes_during_sync) < 0) { brain->failed = TRUE; return; } - if (changes_during_sync) + if (state.changes_during_sync) brain->changes_during_sync = TRUE; } + brain->mailbox_state = state; dsync_ibc_send_mailbox_state(brain->ibc, &state); } @@ -242,7 +242,20 @@ static bool dsync_brain_recv_last_common(struct dsync_brain *brain) return TRUE; } i_assert(brain->box_send_state == DSYNC_BOX_STATE_DONE); - brain->mailbox_state = state; + i_assert(memcmp(state.mailbox_guid, brain->local_dsync_box.mailbox_guid, + sizeof(state.mailbox_guid)) == 0); + + /* normally the last_common_* values should be the same in local and + remote, but during unexpected changes they may differ. use the + values that are lower as the final state. */ + if (brain->mailbox_state.last_common_uid > state.last_common_uid) + brain->mailbox_state.last_common_uid = state.last_common_uid; + if (brain->mailbox_state.last_common_modseq > state.last_common_modseq) + brain->mailbox_state.last_common_modseq = state.last_common_modseq; + if (brain->mailbox_state.last_common_pvt_modseq > state.last_common_pvt_modseq) + brain->mailbox_state.last_common_pvt_modseq = state.last_common_pvt_modseq; + if (state.changes_during_sync) + brain->changes_during_sync = TRUE; dsync_brain_sync_mailbox_deinit(brain); return TRUE; diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index 9b42a5e033..6c50c3a5a8 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -72,7 +72,8 @@ static const struct { { .name = "mailbox_state", .chr = 'S', .required_keys = "mailbox_guid last_uidvalidity last_common_uid " - "last_common_modseq last_common_pvt_modseq" + "last_common_modseq last_common_pvt_modseq", + .optional_keys = "changes_during_sync" }, { .name = "mailbox_tree_node", .chr = 'N', @@ -677,6 +678,8 @@ dsync_ibc_stream_send_mailbox_state(struct dsync_ibc *_ibc, dec2str(state->last_common_modseq)); dsync_serializer_encode_add(encoder, "last_common_pvt_modseq", dec2str(state->last_common_pvt_modseq)); + if (state->changes_during_sync) + dsync_serializer_encode_add(encoder, "changes_during_sync", ""); dsync_serializer_encode_finish(&encoder, str); dsync_ibc_stream_send_string(ibc, str); @@ -722,6 +725,8 @@ dsync_ibc_stream_recv_mailbox_state(struct dsync_ibc *_ibc, dsync_ibc_input_error(ibc, decoder, "Invalid last_common_pvt_modseq"); return DSYNC_IBC_RECV_RET_TRYAGAIN; } + if (dsync_deserializer_decode_try(decoder, "changes_during_sync", &value)) + state_r->changes_during_sync = TRUE; return DSYNC_IBC_RECV_RET_OK; } diff --git a/src/doveadm/dsync/dsync-mailbox-state.h b/src/doveadm/dsync/dsync-mailbox-state.h index c242f104ea..2b68123d96 100644 --- a/src/doveadm/dsync/dsync-mailbox-state.h +++ b/src/doveadm/dsync/dsync-mailbox-state.h @@ -9,6 +9,7 @@ struct dsync_mailbox_state { uint32_t last_common_uid; uint64_t last_common_modseq; uint64_t last_common_pvt_modseq; + bool changes_during_sync; }; ARRAY_DEFINE_TYPE(dsync_mailbox_state, struct dsync_mailbox_state); HASH_TABLE_DEFINE_TYPE(dsync_mailbox_state, uint8_t *, struct dsync_mailbox_state *); -- 2.47.3