dovecot-2.0: director: Preserve old mail server state when a new...

dovecot at dovecot.org dovecot at dovecot.org
Thu May 20 11:43:51 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/5f77c91f3df0
changeset: 11350:5f77c91f3df0
user:      Timo Sirainen <tss at iki.fi>
date:      Thu May 20 10:43:47 2010 +0200
description:
director: Preserve old mail server state when a new director connects to ring.

diffstat:

 src/director/director-connection.c |  48 +++++++++++++++++++++++-
 1 files changed, 46 insertions(+), 2 deletions(-)

diffs (100 lines):

diff -r 350208d17fcd -r 5f77c91f3df0 src/director/director-connection.c
--- a/src/director/director-connection.c	Thu May 20 10:43:19 2010 +0200
+++ b/src/director/director-connection.c	Thu May 20 10:43:47 2010 +0200
@@ -47,6 +47,7 @@
 	unsigned int version_received:1;
 	unsigned int me_received:1;
 	unsigned int handshake_received:1;
+	unsigned int ignore_host_events:1;
 };
 
 static void director_connection_ping(struct director_connection *conn);
@@ -233,6 +234,34 @@
 }
 
 static bool
+director_cmd_host_hand_start(struct director_connection *conn,
+			     const char *const *args)
+{
+	const ARRAY_TYPE(mail_host) *hosts;
+	struct mail_host *const *hostp;
+	unsigned int remote_ring_completed;
+
+	if (args == NULL || str_to_uint(args[0], &remote_ring_completed) < 0) {
+		i_error("director(%s): Invalid HOST-HAND-START args",
+			conn->name);
+		return FALSE;
+	}
+
+	if (remote_ring_completed && !conn->dir->ring_handshaked) {
+		/* clear everything we have and use only what remote sends us */
+		hosts = mail_hosts_get();
+		while (array_count(hosts) > 0) {
+			hostp = array_idx(hosts, 0);
+			director_remove_host(conn->dir, conn->host, *hostp);
+		}
+	} else if (!remote_ring_completed && conn->dir->ring_handshaked) {
+		/* ignore whatever remote sends */
+		conn->ignore_host_events = TRUE;
+	}
+	return TRUE;
+}
+
+static bool
 director_cmd_host(struct director_connection *conn, const char *const *args)
 {
 	struct mail_host *host;
@@ -246,6 +275,11 @@
 		i_error("director(%s): Invalid HOST args", conn->name);
 		return FALSE;
 	}
+	if (conn->ignore_host_events) {
+		/* remote is sending hosts in a handshake, but it doesn't have
+		   a completed ring and we do. */
+		return TRUE;
+	}
 
 	host = mail_host_lookup(&ip);
 	if (host == NULL) {
@@ -363,6 +397,13 @@
 		return director_cmd_director(conn, args);
 	if (conn->in && strcmp(cmd, "HOST") == 0 && conn->me_received)
 		return director_cmd_host(conn, args);
+	if (strcmp(cmd, "HOST-HAND-START") == 0)
+		return director_cmd_host_hand_start(conn, args);
+	if (strcmp(cmd, "HOST-HAND-END") == 0) {
+		conn->ignore_host_events = TRUE;
+		return TRUE;
+	}
+
 	/* only incoming connections get a USER list */
 	if (conn->in && strcmp(cmd, "USER") == 0 && conn->me_received)
 		return director_handshake_cmd_user(conn, args);
@@ -536,14 +577,17 @@
 	}
 }
 
-static void director_connection_send_hosts(string_t *str)
+static void
+director_connection_send_hosts(struct director_connection *conn, string_t *str)
 {
 	struct mail_host *const *hostp;
 
+	str_printfa(str, "HOST-HAND-START\t%u\n", conn->dir->ring_handshaked);
 	array_foreach(mail_hosts_get(), hostp) {
 		str_printfa(str, "HOST\t%s\t%u\n",
 			    net_ip2addr(&(*hostp)->ip), (*hostp)->vhost_count);
 	}
+	str_printfa(str, "HOST-HAND-END\t%u\n", conn->dir->ring_handshaked);
 }
 
 static int director_connection_send_users(struct director_connection *conn)
@@ -650,7 +694,7 @@
 
 	director_connection_send_handshake(conn);
 	director_connection_send_directors(conn, str);
-	director_connection_send_hosts(str);
+	director_connection_send_hosts(conn, str);
 	director_connection_send(conn, str_c(str));
 
 	conn->user_iter = user_directory_iter_init(dir->users);


More information about the dovecot-cvs mailing list