]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Support syncing storages with 128bit GUIDs <-> string GUIDs.
authorTimo Sirainen <tss@iki.fi>
Sun, 17 Nov 2013 15:59:05 +0000 (17:59 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 17 Nov 2013 15:59:05 +0000 (17:59 +0200)
src/doveadm/dsync/dsync-brain-mailbox.c
src/doveadm/dsync/dsync-ibc-stream.c
src/doveadm/dsync/dsync-mailbox-import.c
src/doveadm/dsync/dsync-mailbox-import.h
src/doveadm/dsync/dsync-mailbox.h
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h

index 087ddf35e08d8688ccb50482d874ba7debfddd9f..d6e3618accff88a9ce2ec5441a63a1cdde5c5441 100644 (file)
@@ -184,6 +184,9 @@ dsync_brain_sync_mailbox_init_remote(struct dsync_brain *brain,
            (remote_dsync_box->have_save_guids ||
             (brain->backup_recv && remote_dsync_box->have_guids)))
                import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS;
+       if (brain->local_dsync_box.have_only_guid128 ||
+           remote_dsync_box->have_only_guid128)
+               import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128;
 
        brain->box_importer = brain->backup_send ? NULL :
                dsync_mailbox_import_init(brain->box, brain->log_scan,
index cf64628ef5e844b0b948bc42e05e1c1df2c92786..b4844a3fd42623fa9137f9b5ea9f7b341c46b3da 100644 (file)
@@ -98,7 +98,7 @@ static const struct {
          .chr = 'B',
          .required_keys = "mailbox_guid uid_validity uid_next messages_count "
                "first_recent_uid highest_modseq highest_pvt_modseq",
-         .optional_keys = "mailbox_lost cache_fields have_guids have_save_guids"
+         .optional_keys = "mailbox_lost cache_fields have_guids have_save_guids have_only_guid128"
        },
        { .name = "mailbox_attribute",
          .chr = 'A',
@@ -1178,6 +1178,8 @@ dsync_ibc_stream_send_mailbox(struct dsync_ibc *_ibc,
                dsync_serializer_encode_add(encoder, "have_guids", "");
        if (dsync_box->have_save_guids)
                dsync_serializer_encode_add(encoder, "have_save_guids", "");
+       if (dsync_box->have_only_guid128)
+               dsync_serializer_encode_add(encoder, "have_only_guid128", "");
        dsync_serializer_encode_add(encoder, "uid_validity",
                                    dec2str(dsync_box->uid_validity));
        dsync_serializer_encode_add(encoder, "uid_next",
@@ -1281,6 +1283,8 @@ dsync_ibc_stream_recv_mailbox(struct dsync_ibc *_ibc,
        if (dsync_deserializer_decode_try(decoder, "have_save_guids", &value) ||
            (box->have_guids && ibc->minor_version < DSYNC_PROTOCOL_MINOR_HAVE_SAVE_GUID))
                box->have_save_guids = TRUE;
+       if (dsync_deserializer_decode_try(decoder, "have_only_guid128", &value))
+               box->have_only_guid128 = TRUE;
        value = dsync_deserializer_decode_get(decoder, "uid_validity");
        if (str_to_uint32(value, &box->uid_validity) < 0) {
                dsync_ibc_input_error(ibc, decoder, "Invalid uid_validity");
index ac0917d47b17633c7d62a72f5706846fca1f6d54..7f528d6234716ce22906ec538c9799cc62d3007e 100644 (file)
@@ -103,6 +103,7 @@ struct dsync_mailbox_importer {
        unsigned int master_brain:1;
        unsigned int revert_local_changes:1;
        unsigned int mails_have_guids:1;
+       unsigned int mails_use_guid128:1;
 };
 
 static void dsync_mailbox_save_newmails(struct dsync_mailbox_importer *importer,
@@ -218,6 +219,8 @@ dsync_mailbox_import_init(struct mailbox *box,
        importer->debug = (flags & DSYNC_MAILBOX_IMPORT_FLAG_DEBUG) != 0;
        importer->mails_have_guids =
                (flags & DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS) != 0;
+       importer->mails_use_guid128 =
+               (flags & DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128) != 0;
 
        mailbox_get_open_status(importer->box, STATUS_UIDNEXT |
                                STATUS_HIGHESTMODSEQ | STATUS_HIGHESTPVTMODSEQ,
@@ -463,12 +466,14 @@ static void dsync_mail_error(struct dsync_mailbox_importer *importer,
 }
 
 static bool
-dsync_mail_change_guid_equals(const struct dsync_mail_change *change,
+dsync_mail_change_guid_equals(struct dsync_mailbox_importer *importer,
+                             const struct dsync_mail_change *change,
                              const char *guid, const char **cmp_guid_r)
 {
        guid_128_t guid_128, change_guid_128;
 
-       if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE) {
+       if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE &&
+           !importer->mails_use_guid128) {
                if (cmp_guid_r != NULL)
                        *cmp_guid_r = change->guid;
                return strcmp(change->guid, guid) == 0;
@@ -480,7 +485,7 @@ dsync_mail_change_guid_equals(const struct dsync_mail_change *change,
        mail_generate_guid_128_hash(guid, guid_128);
        if (memcmp(change_guid_128, guid_128, GUID_128_SIZE) != 0) {
                if (cmp_guid_r != NULL) {
-                       *cmp_guid_r = t_strdup_printf("%s(expunged, orig=%s)",
+                       *cmp_guid_r = t_strdup_printf("%s(guid128, orig=%s)",
                                binary_to_hex(change_guid_128, sizeof(change_guid_128)),
                                change->guid);
                }
@@ -760,7 +765,7 @@ dsync_import_set_mail(struct dsync_mailbox_importer *importer,
                dsync_mail_error(importer, importer->mail, "GUID");
                return FALSE;
        }
-       if (!dsync_mail_change_guid_equals(change, guid, &cmp_guid)) {
+       if (!dsync_mail_change_guid_equals(importer, change, guid, &cmp_guid)) {
                dsync_import_unexpected_state(importer, t_strdup_printf(
                        "Unexpected GUID mismatch for UID=%u: %s != %s",
                        change->uid, guid, cmp_guid));
@@ -778,7 +783,8 @@ static bool dsync_check_cur_guid(struct dsync_mailbox_importer *importer,
        if (change->guid == NULL || change->guid[0] == '\0' ||
            importer->cur_guid[0] == '\0')
                return TRUE;
-       if (!dsync_mail_change_guid_equals(change, importer->cur_guid, &cmp_guid)) {
+       if (!dsync_mail_change_guid_equals(importer, change,
+                                          importer->cur_guid, &cmp_guid)) {
                dsync_import_unexpected_state(importer, t_strdup_printf(
                        "Unexpected GUID mismatch (2) for UID=%u: %s != %s",
                        change->uid, importer->cur_guid, cmp_guid));
@@ -1294,7 +1300,8 @@ dsync_mailbox_import_match_msg(struct dsync_mailbox_importer *importer,
 
        if (*change->guid != '\0' && *importer->cur_guid != '\0') {
                /* we have GUIDs, verify them */
-               if (dsync_mail_change_guid_equals(change, importer->cur_guid, NULL))
+               if (dsync_mail_change_guid_equals(importer, change,
+                                                 importer->cur_guid, NULL))
                        return 1;
                else
                        return 0;
@@ -1343,7 +1350,8 @@ dsync_mailbox_find_common_expunged_uid(struct dsync_mailbox_importer *importer,
                return FALSE;
 
        i_assert(local_change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE);
-       if (dsync_mail_change_guid_equals(local_change, change->guid, NULL))
+       if (dsync_mail_change_guid_equals(importer, local_change,
+                                         change->guid, NULL))
                importer->last_common_uid = change->uid;
        else if (change->type != DSYNC_MAIL_CHANGE_TYPE_EXPUNGE)
                dsync_mailbox_common_uid_found(importer);
index 27930f6b45613fed442f4989ac4e3522cbbb5cae..3c19502f29cc98d8c3909659cd13c3c83b656ebf 100644 (file)
@@ -6,7 +6,8 @@ enum dsync_mailbox_import_flags {
        DSYNC_MAILBOX_IMPORT_FLAG_WANT_MAIL_REQUESTS    = 0x02,
        DSYNC_MAILBOX_IMPORT_FLAG_REVERT_LOCAL_CHANGES  = 0x04,
        DSYNC_MAILBOX_IMPORT_FLAG_DEBUG                 = 0x08,
-       DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS      = 0x10
+       DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS      = 0x10,
+       DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128     = 0x20
 };
 
 struct mailbox;
index af9119f8d990dd931493e4cf31351557ae94637d..4e0254369c3a0c0b91a97a19f0bd7ce490b34792 100644 (file)
@@ -8,7 +8,7 @@
 struct dsync_mailbox {
        guid_128_t mailbox_guid;
        bool mailbox_lost;
-       bool have_guids, have_save_guids;
+       bool have_guids, have_save_guids, have_only_guid128;
 
        uint32_t uid_validity, uid_next, messages_count, first_recent_uid;
        uint64_t highest_modseq, highest_pvt_modseq;
index 08018b73be2ca0a566c3b2f018d3e00eb5dcc1de..770e732a11bdb10554e016c5028008f0266c78fc 100644 (file)
@@ -72,7 +72,10 @@ enum mail_storage_class_flags {
        MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_SAVE_GUIDS    = 0x80,
        /* message content can be unstructured binary data
           (e.g. zlib plugin is allowed to compress/decompress mails) */
-       MAIL_STORAGE_CLASS_FLAG_BINARY_DATA     = 0x100
+       MAIL_STORAGE_CLASS_FLAG_BINARY_DATA     = 0x100,
+       /* Message GUIDs can only be 128bit (always set
+          mailbox_status.have_only_guid128) */
+       MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUID128 = 0x200
 };
 
 struct mail_binary_cache {
index a6e8c1c0e6b8afce6d8afe17c2b1e3cb856ba06b..3bd920995e5c27f7fd6edb7eae093d847fc75443 100644 (file)
@@ -1502,6 +1502,8 @@ mailbox_get_status_set_defaults(struct mailbox *box,
                status_r->have_guids = TRUE;
        if ((box->storage->class_flags & MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_SAVE_GUIDS) != 0)
                status_r->have_save_guids = TRUE;
+       if ((box->storage->class_flags & MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUID128) != 0)
+               status_r->have_only_guid128 = TRUE;
 }
 
 int mailbox_get_status(struct mailbox *box,
index 6997a074e3cfdf099bcfb9542e1de507904d535f..ad77cfc7c76695596ea222911342897165b80b13 100644 (file)
@@ -282,6 +282,8 @@ struct mailbox_status {
        unsigned int have_guids:1;
        /* mailbox_save_set_guid() works (always set) */
        unsigned int have_save_guids:1;
+       /* GUIDs are always 128bit (always set) */
+       unsigned int have_only_guid128:1;
 };
 
 struct mailbox_cache_field {