dovecot-2.2: dsync: Use private modseqs to support syncing priva...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 4 01:13:16 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/5d90e2aa1ba8
changeset: 15496:5d90e2aa1ba8
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 04 01:13:05 2013 +0200
description:
dsync: Use private modseqs to support syncing private flags in shared mailboxes.

diffstat:

 src/doveadm/dsync/dsync-brain-mailbox.c        |  24 +++++-
 src/doveadm/dsync/dsync-brain-mails.c          |   3 +
 src/doveadm/dsync/dsync-ibc-stream.c           |  31 ++++++++-
 src/doveadm/dsync/dsync-mail.c                 |   1 +
 src/doveadm/dsync/dsync-mail.h                 |   4 +
 src/doveadm/dsync/dsync-mailbox-export.c       |   4 +-
 src/doveadm/dsync/dsync-mailbox-export.h       |   1 -
 src/doveadm/dsync/dsync-mailbox-import.c       |  73 ++++++++++++++++++-----
 src/doveadm/dsync/dsync-mailbox-import.h       |   3 +
 src/doveadm/dsync/dsync-mailbox-state.c        |   5 +
 src/doveadm/dsync/dsync-mailbox-state.h        |   1 +
 src/doveadm/dsync/dsync-mailbox.h              |   2 +-
 src/doveadm/dsync/dsync-transaction-log-scan.c |  81 +++++++++++++++++--------
 src/doveadm/dsync/dsync-transaction-log-scan.h |   3 +-
 14 files changed, 176 insertions(+), 60 deletions(-)

diffs (truncated from 777 to 300 lines):

diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-brain-mailbox.c
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Fri Jan 04 01:13:05 2013 +0200
@@ -140,17 +140,20 @@
 {
 	enum dsync_mailbox_exporter_flags exporter_flags = 0;
 	uint32_t last_common_uid, highest_wanted_uid;
-	uint64_t last_common_modseq;
+	uint64_t last_common_modseq, last_common_pvt_modseq;
 
 	i_assert(brain->log_scan == NULL);
 
 	last_common_uid = brain->mailbox_state.last_common_uid;
 	last_common_modseq = brain->mailbox_state.last_common_modseq;
+	last_common_pvt_modseq = brain->mailbox_state.last_common_pvt_modseq;
 	highest_wanted_uid = last_common_uid == 0 ?
 		(uint32_t)-1 : last_common_uid;
 	if (dsync_transaction_log_scan_init(brain->box->view,
+					    brain->box->view_pvt,
 					    highest_wanted_uid,
 					    last_common_modseq,
+					    last_common_pvt_modseq,
 					    &brain->log_scan) < 0) {
 		i_error("Failed to read transaction log for mailbox %s",
 			mailbox_get_vname(brain->box));
@@ -165,7 +168,7 @@
 
 	brain->box_exporter = brain->backup_recv ? NULL :
 		dsync_mailbox_export_init(brain->box, brain->log_scan,
-					  last_common_uid, last_common_modseq,
+					  last_common_uid,
 					  exporter_flags);
 	return 0;
 }
@@ -176,7 +179,7 @@
 	enum dsync_mailbox_import_flags import_flags = 0;
 	const struct dsync_mailbox_state *state;
 	uint32_t last_common_uid;
-	uint64_t last_common_modseq;
+	uint64_t last_common_modseq, last_common_pvt_modseq;
 
 	i_assert(brain->box_importer == NULL);
 	i_assert(brain->log_scan != NULL);
@@ -191,9 +194,11 @@
 	if (state != NULL) {
 		last_common_uid = state->last_common_uid;
 		last_common_modseq = state->last_common_modseq;
+		last_common_pvt_modseq = state->last_common_pvt_modseq;
 	} else {
 		last_common_uid = 0;
 		last_common_modseq = 0;
+		last_common_pvt_modseq = 0;
 	}
 
 	if (brain->guid_requests)
@@ -208,9 +213,11 @@
 	brain->box_importer = brain->backup_send ? NULL :
 		dsync_mailbox_import_init(brain->box, brain->log_scan,
 					  last_common_uid, last_common_modseq,
+					  last_common_pvt_modseq,
 					  remote_dsync_box->uid_next,
 					  remote_dsync_box->first_recent_uid,
 					  remote_dsync_box->highest_modseq,
+					  remote_dsync_box->highest_pvt_modseq,
 					  import_flags);
 }
 
@@ -228,13 +235,14 @@
 	}
 	if (brain->box_importer != NULL) {
 		uint32_t last_common_uid;
-		uint64_t last_common_modseq;
+		uint64_t last_common_modseq, last_common_pvt_modseq;
 		bool changes_during_sync;
 
 		i_assert(brain->failed);
 		(void)dsync_mailbox_import_deinit(&brain->box_importer,
 						  &last_common_uid,
 						  &last_common_modseq,
+						  &last_common_pvt_modseq,
 						  &changes_during_sync);
 	}
 	if (brain->log_scan != NULL)
@@ -248,7 +256,8 @@
 {
 	const enum mailbox_status_items status_items =
 		STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_MESSAGES |
-		STATUS_FIRST_RECENT_UID | STATUS_HIGHESTMODSEQ;
+		STATUS_FIRST_RECENT_UID | STATUS_HIGHESTMODSEQ |
+		STATUS_HIGHESTPVTMODSEQ;
 	const enum mailbox_metadata_items metadata_items =
 		MAILBOX_METADATA_CACHE_FIELDS | MAILBOX_METADATA_GUID;
 	struct mailbox_status status;
@@ -283,6 +292,7 @@
 	dsync_box_r->messages_count = status.messages;
 	dsync_box_r->first_recent_uid = status.first_recent_uid;
 	dsync_box_r->highest_modseq = status.highest_modseq;
+	dsync_box_r->highest_pvt_modseq = status.highest_pvt_modseq;
 	dsync_box_r->cache_fields = *metadata.cache_fields;
 	return 1;
 }
@@ -300,7 +310,8 @@
 	return state == NULL ||
 		state->last_uidvalidity != dsync_box->uid_validity ||
 		state->last_common_uid+1 != dsync_box->uid_next ||
-		state->last_common_modseq != dsync_box->highest_modseq;
+		state->last_common_modseq != dsync_box->highest_modseq ||
+		state->last_common_pvt_modseq != dsync_box->highest_pvt_modseq;
 }
 
 static int
@@ -406,6 +417,7 @@
 			   const struct dsync_mailbox *box2)
 {
 	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 ||
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-brain-mails.c
--- a/src/doveadm/dsync/dsync-brain-mails.c	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-mails.c	Fri Jan 04 01:13:05 2013 +0200
@@ -165,10 +165,13 @@
 		state.last_common_uid = brain->local_dsync_box.uid_next-1;
 		state.last_common_modseq =
 			brain->local_dsync_box.highest_modseq;
+		state.last_common_pvt_modseq =
+			brain->local_dsync_box.highest_pvt_modseq;
 	} else {
 		if (dsync_mailbox_import_deinit(&brain->box_importer,
 						&state.last_common_uid,
 						&state.last_common_modseq,
+						&state.last_common_pvt_modseq,
 						&changes_during_sync) < 0) {
 			i_error("Importing mailbox %s failed",
 				mailbox_get_vname(brain->box));
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-ibc-stream.c
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Fri Jan 04 01:13:05 2013 +0200
@@ -66,7 +66,7 @@
 	{ .name = "mailbox_state",
 	  .chr = 'S',
 	  .required_keys = "mailbox_guid last_uidvalidity last_common_uid "
-	  	"last_common_modseq"
+	  	"last_common_modseq last_common_pvt_modseq"
 	},
 	{ .name = "mailbox_tree_node",
 	  .chr = 'N',
@@ -81,14 +81,14 @@
 	},
 	{ .name = "mailbox",
 	  .chr = 'B',
-	  .required_keys = "mailbox_guid uid_validity uid_next "
-		"messages_count first_recent_uid highest_modseq",
+	  .required_keys = "mailbox_guid uid_validity uid_next messages_count "
+		"first_recent_uid highest_modseq highest_pvt_modseq",
 	  .optional_keys = "mailbox_lost cache_fields"
 	},
 	{ .name = "mail_change",
 	  .chr = 'C',
 	  .required_keys = "type uid",
-	  .optional_keys = "guid hdr_hash modseq save_timestamp "
+	  .optional_keys = "guid hdr_hash modseq pvt_modseq save_timestamp "
 	  	"add_flags remove_flags final_flags "
 	  	"keywords_reset keyword_changes"
 	},
@@ -642,6 +642,8 @@
 				    dec2str(state->last_common_uid));
 	dsync_serializer_encode_add(encoder, "last_common_modseq",
 				    dec2str(state->last_common_modseq));
+	dsync_serializer_encode_add(encoder, "last_common_pvt_modseq",
+				    dec2str(state->last_common_pvt_modseq));
 
 	dsync_serializer_encode_finish(&encoder, str);
 	dsync_ibc_stream_send_string(ibc, str);
@@ -682,6 +684,11 @@
 		dsync_ibc_input_error(ibc, decoder, "Invalid last_common_modseq");
 		return DSYNC_IBC_RECV_RET_TRYAGAIN;
 	}
+	value = dsync_deserializer_decode_get(decoder, "last_common_pvt_modseq");
+	if (str_to_uint64(value, &state_r->last_common_pvt_modseq) < 0) {
+		dsync_ibc_input_error(ibc, decoder, "Invalid last_common_pvt_modseq");
+		return DSYNC_IBC_RECV_RET_TRYAGAIN;
+	}
 	return DSYNC_IBC_RECV_RET_OK;
 }
 
@@ -1002,6 +1009,8 @@
 				    dec2str(dsync_box->first_recent_uid));
 	dsync_serializer_encode_add(encoder, "highest_modseq",
 				    dec2str(dsync_box->highest_modseq));
+	dsync_serializer_encode_add(encoder, "highest_pvt_modseq",
+				    dec2str(dsync_box->highest_pvt_modseq));
 
 	value = get_cache_fields(ibc, dsync_box);
 	if (value != NULL)
@@ -1113,6 +1122,11 @@
 		dsync_ibc_input_error(ibc, decoder, "Invalid highest_modseq");
 		return DSYNC_IBC_RECV_RET_TRYAGAIN;
 	}
+	value = dsync_deserializer_decode_get(decoder, "highest_pvt_modseq");
+	if (str_to_uint64(value, &box->highest_pvt_modseq) < 0) {
+		dsync_ibc_input_error(ibc, decoder, "Invalid highest_pvt_modseq");
+		return DSYNC_IBC_RECV_RET_TRYAGAIN;
+	}
 
 	p_array_init(&box->cache_fields, pool, 32);
 	if (dsync_deserializer_decode_try(decoder, "cache_fields", &value)) {
@@ -1164,6 +1178,10 @@
 		dsync_serializer_encode_add(encoder, "modseq",
 					    dec2str(change->modseq));
 	}
+	if (change->pvt_modseq != 0) {
+		dsync_serializer_encode_add(encoder, "pvt_modseq",
+					    dec2str(change->pvt_modseq));
+	}
 	if (change->save_timestamp != 0) {
 		dsync_serializer_encode_add(encoder, "save_timestamp",
 					    dec2str(change->save_timestamp));
@@ -1252,6 +1270,11 @@
 		dsync_ibc_input_error(ibc, decoder, "Invalid modseq");
 		return DSYNC_IBC_RECV_RET_TRYAGAIN;
 	}
+	if (dsync_deserializer_decode_try(decoder, "pvt_modseq", &value) &&
+	    str_to_uint64(value, &change->pvt_modseq) < 0) {
+		dsync_ibc_input_error(ibc, decoder, "Invalid pvt_modseq");
+		return DSYNC_IBC_RECV_RET_TRYAGAIN;
+	}
 	if (dsync_deserializer_decode_try(decoder, "save_timestamp", &value) &&
 	    str_to_time(value, &change->save_timestamp) < 0) {
 		dsync_ibc_input_error(ibc, decoder, "Invalid save_timestamp");
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-mail.c
--- a/src/doveadm/dsync/dsync-mail.c	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-mail.c	Fri Jan 04 01:13:05 2013 +0200
@@ -73,6 +73,7 @@
 	}
 	dest_r->hdr_hash = p_strdup(pool, src->hdr_hash);
 	dest_r->modseq = src->modseq;
+	dest_r->pvt_modseq = src->pvt_modseq;
 	dest_r->save_timestamp = src->save_timestamp;
 
 	dest_r->add_flags = src->add_flags;
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-mail.h
--- a/src/doveadm/dsync/dsync-mail.h	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-mail.h	Fri Jan 04 01:13:05 2013 +0200
@@ -49,6 +49,9 @@
 
 	/* Message's current modseq (saves, flag changes) */
 	uint64_t modseq;
+	/* Message's current private modseq (for private flags in
+	   shared mailboxes, otherwise 0) */
+	uint64_t pvt_modseq;
 	/* Message's save timestamp (saves) */
 	time_t save_timestamp;
 
@@ -57,6 +60,7 @@
 	/* Flags added/removed since last sync, and final flags containing
 	   flags that exist now but haven't changed */
 	uint8_t add_flags, remove_flags, final_flags;
+	uint8_t add_pvt_flags, remove_pvt_flags;
 	/* Remove all keywords before applying changes. This is used only with
 	   old transaction logs, new ones never reset keywords (just explicitly
 	   remove unwanted keywords) */
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-mailbox-export.c
--- a/src/doveadm/dsync/dsync-mailbox-export.c	Fri Jan 04 01:12:24 2013 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-export.c	Fri Jan 04 01:13:05 2013 +0200
@@ -21,7 +21,6 @@
 	struct mailbox *box;
 	struct dsync_transaction_log_scan *log_scan;
 	uint32_t last_common_uid;
-	uint64_t last_common_modseq;
 
 	struct mailbox_transaction_context *trans;
 	struct mail_search_context *search_ctx;
@@ -99,6 +98,7 @@
 	i_assert((change->add_flags & change->remove_flags) == 0);
 
 	change->modseq = mail_get_modseq(mail);
+	change->pvt_modseq = mail_get_pvt_modseq(mail);
 	change->final_flags = mail_get_flags(mail) & MAIL_FLAGS_NONRECENT;
 
 	keywords = mail_get_keywords(mail);
@@ -416,7 +416,6 @@
 dsync_mailbox_export_init(struct mailbox *box,
 			  struct dsync_transaction_log_scan *log_scan,
 			  uint32_t last_common_uid,
-			  uint64_t last_common_modseq,
 			  enum dsync_mailbox_exporter_flags flags)
 {
 	struct dsync_mailbox_exporter *exporter;
@@ -429,7 +428,6 @@
 	exporter->box = box;
 	exporter->log_scan = log_scan;
 	exporter->last_common_uid = last_common_uid;
-	exporter->last_common_modseq = last_common_modseq;
 	exporter->auto_export_mails =
 		(flags & DSYNC_MAILBOX_EXPORTER_FLAG_AUTO_EXPORT_MAILS) != 0;
 	exporter->mails_have_guids =
diff -r 69371578720f -r 5d90e2aa1ba8 src/doveadm/dsync/dsync-mailbox-export.h
--- a/src/doveadm/dsync/dsync-mailbox-export.h	Fri Jan 04 01:12:24 2013 +0200


More information about the dovecot-cvs mailing list