]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Merge last-common-* values from both local and remote when they differ.
authorTimo Sirainen <tss@iki.fi>
Sat, 16 Feb 2013 15:17:14 +0000 (17:17 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 16 Feb 2013 15:17:14 +0000 (17:17 +0200)
src/doveadm/dsync/dsync-brain-mails.c
src/doveadm/dsync/dsync-ibc-stream.c
src/doveadm/dsync/dsync-mailbox-state.h

index 24346566f8523386615fe7850670799b59f50567..87e5069e0d3f61c30d5118987619f0fa65b566ef 100644 (file)
@@ -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;
index 9b42a5e03303c404710fb98b51e0fb83b0da5e3b..6c50c3a5a89cbe2255ef0b7d4768aa5629aa2612 100644 (file)
@@ -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;
 }
 
index c242f104ead375bf2dc4e42a4db90d424699419e..2b68123d964a1b6be5cf408ebd952746f05f2771 100644 (file)
@@ -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 *);