bool dsync_boxes_need_sync(struct dsync_brain *brain,
const struct dsync_mailbox *box1,
- const struct dsync_mailbox *box2)
+ const struct dsync_mailbox *box2,
+ const char **reason_r)
{
if (brain->no_mail_sync)
return FALSE;
- if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_CHANGED)
+ if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_CHANGED) {
+ *reason_r = "Full sync";
return TRUE;
- return box1->highest_modseq != box2->highest_modseq ||
- box1->highest_pvt_modseq != box2->highest_pvt_modseq ||
- box1->messages_count != box2->messages_count ||
- box1->uid_next != box2->uid_next ||
- box1->uid_validity != box2->uid_validity ||
- box1->first_recent_uid != box2->first_recent_uid;
+ }
+ if (box1->uid_validity != box2->uid_validity)
+ *reason_r = t_strdup_printf("UIDVALIDITY changed: %u -> %u",
+ box1->uid_validity, box2->uid_validity);
+ else if (box1->uid_next != box2->uid_next)
+ *reason_r = t_strdup_printf("UIDNEXT changed: %u -> %u",
+ box1->uid_next, box2->uid_next);
+ else if (box1->messages_count != box2->messages_count)
+ *reason_r = t_strdup_printf("Message count changed: %u -> %u",
+ box1->messages_count, box2->messages_count);
+ else if (box1->highest_modseq != box2->highest_modseq) {
+ *reason_r = t_strdup_printf("HIGHESTMODSEQ changed %"
+ PRIu64" -> %"PRIu64,
+ box1->highest_modseq,
+ box2->highest_modseq);
+ if (box1->highest_modseq == 0 ||
+ box2->highest_modseq == 0) {
+ *reason_r = t_strdup_printf(
+ "%s (Permanent MODSEQs aren't supported)",
+ *reason_r);
+ }
+ } else if (box1->highest_pvt_modseq != box2->highest_pvt_modseq)
+ *reason_r = t_strdup_printf("Private HIGHESTMODSEQ changed %"
+ PRIu64" -> %"PRIu64,
+ box1->highest_pvt_modseq,
+ box2->highest_pvt_modseq);
+ else if (box1->first_recent_uid != box2->first_recent_uid)
+ *reason_r = t_strdup_printf("First RECENT UID changed: %u -> %u",
+ box1->first_recent_uid, box2->first_recent_uid);
+ else
+ return FALSE;
+ return TRUE;
}
static int
struct dsync_mailbox local_dsync_box;
struct mailbox *box;
struct file_lock *lock;
- const char *errstr, *resync_reason;
+ const char *errstr, *resync_reason, *reason;
enum mail_error error;
int ret;
bool resync;
resync = !dsync_brain_mailbox_update_pre(brain, box, &local_dsync_box,
dsync_box, &resync_reason);
- if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box)) {
+ if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box, &reason)) {
/* no fields appear to have changed, skip this mailbox */
if (brain->debug) {
i_debug("brain %c: Skipping unchanged mailbox %s",
mailbox_free(&box);
return TRUE;
}
+ if (brain->debug) {
+ i_debug("brain %c: Syncing mailbox %s: %s",
+ brain->master_brain ? 'M' : 'S',
+ guid_128_to_string(dsync_box->mailbox_guid), reason);
+ }
/* start export/import */
dsync_brain_sync_mailbox_init(brain, box, lock, &local_dsync_box, FALSE);
static bool dsync_brain_master_sync_recv_mailbox(struct dsync_brain *brain)
{
const struct dsync_mailbox *dsync_box;
- const char *resync_reason;
+ const char *resync_reason, *reason;
enum dsync_ibc_recv_ret ret;
bool resync;
&brain->local_dsync_box,
dsync_box, &resync_reason);
- if (!dsync_boxes_need_sync(brain, &brain->local_dsync_box, dsync_box)) {
+ if (!dsync_boxes_need_sync(brain, &brain->local_dsync_box, dsync_box,
+ &reason)) {
/* no fields appear to have changed, skip this mailbox */
dsync_brain_sync_mailbox_deinit(brain);
return TRUE;
}
+ if (brain->debug) {
+ i_debug("brain %c: Syncing mailbox %s: %s",
+ brain->master_brain ? 'M' : 'S',
+ guid_128_to_string(dsync_box->mailbox_guid), reason);
+ }
if ((ret = dsync_brain_sync_mailbox_open(brain, dsync_box)) < 0)
return TRUE;
if (resync)