dovecot-2.0: dsync: Write mailbox changelog records using origin...

dovecot at dovecot.org dovecot at dovecot.org
Mon Dec 21 22:17:25 EET 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/eba3e50fef36
changeset: 10519:eba3e50fef36
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Dec 21 15:17:08 2009 -0500
description:
dsync: Write mailbox changelog records using original timestamps.

diffstat:

15 files changed, 121 insertions(+), 75 deletions(-)
src/dsync/dsync-brain.c                 |   36 +++++++++++++++---------
src/dsync/dsync-data.h                  |    2 -
src/dsync/dsync-proxy-client.c          |   12 ++++----
src/dsync/dsync-proxy-server-cmd.c      |   18 ++++++++----
src/dsync/dsync-proxy.c                 |    4 +-
src/dsync/dsync-worker-local.c          |   46 ++++++++++++++++++++-----------
src/dsync/dsync-worker-private.h        |    4 +-
src/dsync/dsync-worker.c                |   14 ++++-----
src/dsync/dsync-worker.h                |    5 ++-
src/dsync/test-dsync-brain.c            |    3 +-
src/dsync/test-dsync-proxy-server-cmd.c |   16 ++++++----
src/dsync/test-dsync-worker.c           |    8 ++---
src/lib-storage/mailbox-list-private.h  |    3 --
src/lib-storage/mailbox-list.c          |   18 ++++++++----
src/lib-storage/mailbox-list.h          |    7 +++-

diffs (truncated from 685 to 300 lines):

diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-brain.c
--- a/src/dsync/dsync-brain.c	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-brain.c	Mon Dec 21 15:17:08 2009 -0500
@@ -279,13 +279,13 @@ static void dsync_brain_sync_mailboxes(s
 			/* delete from dest too */
 			if (!dest_deleted) {
 				dsync_worker_delete_mailbox(brain->dest_worker,
-					&dest_boxes[dest]->mailbox_guid);
+							    src_boxes[src]);
 			}
 			src++; dest++;
 		} else if (dest_deleted) {
 			/* delete from src too */
 			dsync_worker_delete_mailbox(brain->src_worker,
-				&src_boxes[src]->mailbox_guid);
+						    dest_boxes[dest]);
 			src++; dest++;
 		} else {
 			src++; dest++;
@@ -315,7 +315,8 @@ static void dsync_brain_sync_mailboxes(s
 
 static bool
 dsync_brain_is_unsubscribed(struct dsync_brain_subs_list *list,
-			    const struct dsync_worker_subscription *subs)
+			    const struct dsync_worker_subscription *subs,
+			    time_t *last_change_r)
 {
 	const struct dsync_worker_unsubscription *unsubs;
 	struct dsync_worker_unsubscription lookup;
@@ -324,16 +325,23 @@ dsync_brain_is_unsubscribed(struct dsync
 	dsync_str_sha_to_guid(subs->storage_name, &lookup.name_sha1);
 	unsubs = array_bsearch(&list->unsubscriptions, &lookup,
 			       dsync_worker_unsubscription_cmp);
-	if (unsubs == NULL)
+	if (unsubs == NULL) {
+		*last_change_r = 0;
 		return FALSE;
-	else
-		return unsubs->last_change > subs->last_change;
+	} else if (unsubs->last_change <= subs->last_change) {
+		*last_change_r = subs->last_change;
+		return FALSE;
+	} else {
+		*last_change_r = unsubs->last_change;
+		return TRUE;
+	}
 }
 
 static void dsync_brain_sync_subscriptions(struct dsync_brain *brain)
 {
 	const struct dsync_worker_subscription *src_subs, *dest_subs;
 	unsigned int src, dest, src_count, dest_count;
+	time_t last_change;
 	int ret;
 
 	/* subscriptions are sorted by name. */
@@ -358,27 +366,29 @@ static void dsync_brain_sync_subscriptio
 		if (ret < 0) {
 			/* subscribed only in source */
 			if (dsync_brain_is_unsubscribed(brain->dest_subs_list,
-							&src_subs[src])) {
+							&src_subs[src],
+							&last_change)) {
 				dsync_worker_set_subscribed(brain->src_worker,
 							    src_subs[src].vname,
-							    FALSE);
+							    last_change, FALSE);
 			} else {
 				dsync_worker_set_subscribed(brain->dest_worker,
 							    src_subs[src].vname,
-							    TRUE);
+							    last_change, TRUE);
 			}
 			src++;
 		} else {
 			/* subscribed only in dest */
 			if (dsync_brain_is_unsubscribed(brain->src_subs_list,
-							&dest_subs[dest])) {
+							&dest_subs[dest],
+							&last_change)) {
 				dsync_worker_set_subscribed(brain->dest_worker,
 							    dest_subs[dest].vname,
-							    FALSE);
+							    last_change, FALSE);
 			} else {
 				dsync_worker_set_subscribed(brain->src_worker,
 							    dest_subs[dest].vname,
-							    TRUE);
+							    last_change, TRUE);
 			}
 			dest++;
 		}
@@ -532,7 +542,7 @@ dsync_brain_sync_rename_mailbox(struct d
 dsync_brain_sync_rename_mailbox(struct dsync_brain *brain,
 				const struct dsync_brain_mailbox *mailbox)
 {
-	if (mailbox->src->last_renamed > mailbox->dest->last_renamed) {
+	if (mailbox->src->last_changed > mailbox->dest->last_changed) {
 		dsync_worker_rename_mailbox(brain->dest_worker,
 					    &mailbox->box.mailbox_guid,
 					    mailbox->src);
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-data.h
--- a/src/dsync/dsync-data.h	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-data.h	Mon Dec 21 15:17:08 2009 -0500
@@ -24,7 +24,7 @@ struct dsync_mailbox {
 
 	uint32_t uid_validity, uid_next;
 	uint64_t highest_modseq;
-	time_t last_renamed;
+	time_t last_changed;
 	enum dsync_mailbox_flags flags;
 	ARRAY_TYPE(const_string) cache_fields;
 };
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy-client.c	Mon Dec 21 15:17:08 2009 -0500
@@ -545,7 +545,8 @@ proxy_client_worker_subs_iter_deinit(str
 
 static void
 proxy_client_worker_set_subscribed(struct dsync_worker *_worker,
-				   const char *name, bool set)
+				   const char *name, time_t last_change,
+				   bool set)
 {
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
@@ -555,7 +556,8 @@ proxy_client_worker_set_subscribed(struc
 
 		str_append(str, "SUBS-SET\t");
 		str_tabescape_write(str, name);
-		str_printfa(str, "\t%d\n", set ? 1 : 0);
+		str_printfa(str, "\t%s\t%d\n", dec2str(last_change),
+			    set ? 1 : 0);
 		o_stream_send(worker->output, str_data(str), str_len(str));
 	} T_END;
 }
@@ -678,7 +680,7 @@ proxy_client_worker_create_mailbox(struc
 
 static void
 proxy_client_worker_delete_mailbox(struct dsync_worker *_worker,
-				   const mailbox_guid_t *mailbox)
+				   const struct dsync_mailbox *dsync_box)
 {
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
@@ -689,8 +691,8 @@ proxy_client_worker_delete_mailbox(struc
 		string_t *str = t_str_new(128);
 
 		str_append(str, "BOX-DELETE\t");
-		dsync_proxy_mailbox_guid_export(str, mailbox);
-		str_append_c(str, '\n');
+		dsync_proxy_mailbox_guid_export(str, &dsync_box->mailbox_guid);
+		str_printfa(str, "\t%s\n", dec2str(dsync_box->last_changed));
 		o_stream_send(worker->output, str_data(str), str_len(str));
 	} T_END;
 }
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy-server-cmd.c
--- a/src/dsync/dsync-proxy-server-cmd.c	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy-server-cmd.c	Mon Dec 21 15:17:08 2009 -0500
@@ -151,13 +151,14 @@ static int
 static int
 cmd_subs_set(struct dsync_proxy_server *server, const char *const *args)
 {
-	if (args[0] == NULL || args[1] == NULL) {
+	if (str_array_length(args) < 3) {
 		i_error("subs-set: Missing parameters");
 		return -1;
 	}
 
 	dsync_worker_set_subscribed(server->worker, args[0],
-				    strcmp(args[1], "1") == 0);
+				    strtoul(args[1], NULL, 10),
+				    strcmp(args[2], "1") == 0);
 	return 1;
 }
 
@@ -244,14 +245,19 @@ cmd_box_delete(struct dsync_proxy_server
 cmd_box_delete(struct dsync_proxy_server *server, const char *const *args)
 {
 	mailbox_guid_t guid;
-
-	if (args[0] == NULL ||
-	    dsync_proxy_mailbox_guid_import(args[0], &guid) < 0) {
+	struct dsync_mailbox dsync_box;
+
+	if (str_array_length(args) < 2)
+		return -1;
+	if (dsync_proxy_mailbox_guid_import(args[0], &guid) < 0) {
 		i_error("box-delete: Invalid mailbox GUID '%s'", args[0]);
 		return -1;
 	}
 
-	dsync_worker_delete_mailbox(server->worker, &guid);
+	memset(&dsync_box, 0, sizeof(dsync_box));
+	dsync_box.mailbox_guid = guid;
+	dsync_box.last_changed = strtoul(args[1], NULL, 10);
+	dsync_worker_delete_mailbox(server->worker, &dsync_box);
 	return 1;
 }
 
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy.c
--- a/src/dsync/dsync-proxy.c	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy.c	Mon Dec 21 15:17:08 2009 -0500
@@ -163,7 +163,7 @@ void dsync_proxy_mailbox_export(string_t
 	str_tabescape_write(str, s);
 	str_append_c(str, '\t');
 	dsync_proxy_mailbox_guid_export(str, &box->dir_guid);
-	str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_renamed,
+	str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_changed,
 		    box->flags);
 
 	if (mail_guid_128_is_empty(box->mailbox_guid.guid)) {
@@ -207,7 +207,7 @@ int dsync_proxy_mailbox_import_unescaped
 		*error_r = "Invalid dir GUID";
 		return -1;
 	}
-	box_r->last_renamed = strtoul(args[i++], &p, 10);
+	box_r->last_changed = strtoul(args[i++], &p, 10);
 	if (*p != '\0') {
 		*error_r = "Invalid mailbox last_renamed";
 		return -1;
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c	Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-worker-local.c	Mon Dec 21 15:17:08 2009 -0500
@@ -51,6 +51,7 @@ struct local_dsync_mailbox_change {
 struct local_dsync_mailbox_change {
 	mailbox_guid_t guid;
 	time_t last_renamed;
+	time_t last_deleted;
 	unsigned int deleted_mailbox:1;
 	unsigned int deleted_dir:1;
 };
@@ -126,14 +127,7 @@ dsync_worker_init_local(struct mail_user
 dsync_worker_init_local(struct mail_user *user, char alt_char)
 {
 	struct local_dsync_worker *worker;
-	struct mail_namespace *ns;
 	pool_t pool;
-
-	/* whatever we do, we do it because we're trying to sync,
-	   not because of a user action. don't log these mailbox list changes
-	   so we don't do wrong decisions on future syncs. */
-	for (ns = user->namespaces; ns != NULL; ns = ns->next)
-		mailbox_list_set_changelog_writable(ns->list, FALSE);
 
 	pool = pool_alloconly_create("local dsync worker", 10240);
 	worker = p_new(pool, struct local_dsync_worker, 1);
@@ -181,6 +175,7 @@ dsync_worker_save_mailbox_change(struct 
 				 const struct mailbox_log_record *rec)
 {
 	struct local_dsync_mailbox_change *change;
+	time_t stamp;
 
 	change = hash_table_lookup(worker->mailbox_changes_hash,
 				   rec->mailbox_guid);
@@ -191,16 +186,20 @@ dsync_worker_save_mailbox_change(struct 
 		hash_table_insert(worker->mailbox_changes_hash,
 				  change->guid.guid, change);
 	}
+
+	stamp = mailbox_log_record_get_timestamp(rec);
 	switch (rec->type) {
 	case MAILBOX_LOG_RECORD_DELETE_MAILBOX:
 		change->deleted_mailbox = TRUE;
+		if (change->last_deleted < stamp)
+			change->last_deleted = stamp;
 		break;
 	case MAILBOX_LOG_RECORD_DELETE_DIR:
 		change->deleted_dir = TRUE;
 		break;
 	case MAILBOX_LOG_RECORD_RENAME:
-		change->last_renamed =
-			mailbox_log_record_get_timestamp(rec);
+		if (change->last_renamed < stamp)
+			change->last_renamed = stamp;
 		break;
 	case MAILBOX_LOG_RECORD_SUBSCRIBE:
 	case MAILBOX_LOG_RECORD_UNSUBSCRIBE:
@@ -220,12 +219,14 @@ dsync_worker_save_subscription_change(st
 				      const struct mailbox_log_record *rec)
 {
 	struct local_dsync_subscription_change *change, new_change;
+	time_t stamp;
 
 	memset(&new_change, 0, sizeof(new_change));
 	new_change.list = list;
 	memcpy(new_change.name_sha1.guid, rec->mailbox_guid,
 	       sizeof(new_change.name_sha1.guid));
 
+	stamp = mailbox_log_record_get_timestamp(rec);
 	change = hash_table_lookup(worker->subscription_changes_hash,
 				   &new_change);
 	if (change == NULL) {
@@ -233,7 +234,13 @@ dsync_worker_save_subscription_change(st
 		*change = new_change;
 		hash_table_insert(worker->subscription_changes_hash,
 				  change, change);
-	}
+	} else if (change->last_change > stamp) {
+		/* we've already seen a newer subscriptions state. this is


More information about the dovecot-cvs mailing list