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 ||
&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);
}
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;
{ .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',
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);
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;
}
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 *);