Mercurial > dovecot > core-2.2
diff src/director/director-connection.c @ 13940:9e43af01f147
director: Make sure ring syncing doesn't get lost when directors get disconnected.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Jan 2012 22:21:57 +0200 |
parents | c70965e8b27d |
children | 493ebb2cfc73 |
line wrap: on
line diff
--- a/src/director/director-connection.c Tue Jan 17 17:20:07 2012 +0200 +++ b/src/director/director-connection.c Tue Jan 17 22:21:57 2012 +0200 @@ -675,6 +675,41 @@ return FALSE; } +static void +director_connection_sync_host(struct director_connection *conn, + struct director_host *host, + uint32_t seq, const char *line) +{ + struct director *dir = conn->dir; + + if (host->self) { + if (dir->sync_seq != seq) { + /* stale SYNC event */ + return; + } + + if (!dir->ring_handshaked) { + /* the ring is handshaked */ + director_set_ring_handshaked(dir); + } else if (dir->ring_synced) { + /* duplicate SYNC (which was sent just in case the + previous one got lost) */ + } else { + if (dir->debug) { + i_debug("Ring is synced (%s sent seq=%u)", + conn->name, seq); + } + director_set_ring_synced(dir); + } + } else { + /* forward it to the connection on right */ + if (dir->right != NULL) { + director_connection_send(dir->right, + t_strconcat(line, "\n", NULL)); + } + } +} + static bool director_connection_sync(struct director_connection *conn, const char *const *args, const char *line) { @@ -693,36 +728,16 @@ /* find the originating director. if we don't see it, it was already removed and we can ignore this sync. */ host = director_host_lookup(dir, &ip, port); - if (host == NULL) - return TRUE; - - if (host->self) { - if (dir->sync_seq != seq) { - /* stale SYNC event */ - return TRUE; - } + if (host != NULL) + director_connection_sync_host(conn, host, seq, line); - if (!dir->ring_handshaked) { - /* the ring is handshaked */ - director_set_ring_handshaked(dir); - } else if (dir->ring_synced) { - i_error("Received SYNC from %s (seq=%u) " - "while already synced", conn->name, seq); - return TRUE; - } else { - if (dir->debug) { - i_debug("Ring is synced (%s sent seq=%u)", - conn->name, seq); - } - director_set_ring_synced(dir); - } - return TRUE; - } - - /* forward it to the connection on right */ - if (dir->right != NULL) { + if (!dir->ring_synced && dir->left != NULL && dir->right != NULL && + (host == NULL || !host->self)) { + /* send a new SYNC in case the previous one got dropped */ director_connection_send(dir->right, - t_strconcat(line, "\n", NULL)); + t_strdup_printf("SYNC\t%s\t%u\t%u\n", + net_ip2addr(&dir->self_ip), + dir->self_port, dir->sync_seq)); } return TRUE; }