Update from mailbox format 6 with "reconstruct -V max" does not always add GUIDs. At least shared folders without OPT_IMAP_SHAREDSEEN contain only records with guid set to 0.
It's reproducable on a 2.5.0 installation: - create shared folder - add a message - verify guid (just to be sure): $ /usr/lib/cyrus/bin/reconstruct -G shared-folder shared-folder $ - downgrade to version 6 (or 8 or 9) $ /usr/lib/cyrus/bin/reconstruct -V 6 shared-folder shared-folder Repacked shared-folder to version 6 $ - upgrade $ /usr/lib/cyrus/bin/reconstruct -V max shared-folder shared-folder: updating sync_crc 0 => 3295118465 shared-folder Repacked shared-folder to version 13 $ - now "reconstruct -G" complains about GUID mismatch $ /usr/lib/cyrus/bin/reconstruct -G shared-folder shared-folder uid 1 guid mismatch run reconstruct with -R to fix or -U to remove shared-folder $ Is this intentional? The attached proof-of-concept patch fixes this issue but I might have gotten the details wrong (like version boundaries <10/>=10). It's copy&paste from the following if-clause (+ removal of seen state update). Btw. the last message is a bit misleading: "-G -R" or "-G -U" are necessary. - Norbert
diff --git a/imap/mailbox.c b/imap/mailbox.c index e9aa718..55eee4f 100644 --- a/imap/mailbox.c +++ b/imap/mailbox.c @@ -3273,6 +3273,19 @@ static int mailbox_index_repack(struct mailbox *mailbox, int version) if (!record.uid) continue; /* version changes? */ + if (repack->old_version < 10 && repack->i.minor_version >= 10 && !repack->seqset && record.guid.status == GUID_NULL) { + const char *fname = mailbox_message_fname(mailbox, record.uid); + + /* XXX - re-parse the record iff upgrading past 12 */ + if (message_parse(fname, &record)) { + /* failed to parse, don't try to write out record */ + record.crec.len = 0; + /* and the record is expunged too! */ + record.system_flags |= FLAG_EXPUNGED | FLAG_UNLINKED; + syslog(LOG_ERR, "IOERROR: FATAL - failed to parse file for %s %u, expunging", + repack->mailbox->name, record.uid); + } + } if (repack->old_version < 12 && repack->i.minor_version >= 12 && repack->seqset) { const char *fname = mailbox_message_fname(mailbox, record.uid);