dovecot-2.1: director: Keep track of the highest supported proto...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Mar 7 20:16:44 EET 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/334424e7465e
changeset: 14270:334424e7465e
user: Timo Sirainen <tss at iki.fi>
date: Wed Mar 07 20:16:33 2012 +0200
description:
director: Keep track of the highest supported protocol version in the ring.
diffstat:
src/director/director-connection.c | 41 +++++++++++++++++++------------------
src/director/director.c | 27 ++++++++++++++++++------
src/director/director.h | 8 +++++++
3 files changed, 49 insertions(+), 27 deletions(-)
diffs (194 lines):
diff -r 94de7605f50f -r 334424e7465e src/director/director-connection.c
--- a/src/director/director-connection.c Wed Mar 07 16:58:37 2012 +0200
+++ b/src/director/director-connection.c Wed Mar 07 20:16:33 2012 +0200
@@ -19,10 +19,6 @@
#include <stdlib.h>
#include <unistd.h>
-#define DIRECTOR_VERSION_NAME "director"
-#define DIRECTOR_VERSION_MAJOR 1
-#define DIRECTOR_VERSION_MINOR 0
-
#define MAX_INBUF_SIZE 1024
#define MAX_OUTBUF_SIZE (1024*1024*10)
#define OUTBUF_FLUSH_THRESHOLD (1024*128)
@@ -586,10 +582,8 @@
finished by sending a SYNC. if we get it back, it's done. */
dir->sync_seq++;
director_set_ring_unsynced(dir);
- director_connection_send(dir->right,
- t_strdup_printf("SYNC\t%s\t%u\t%u\n",
- net_ip2addr(&dir->self_ip),
- dir->self_port, dir->sync_seq));
+ director_sync_send(dir, dir->self_host, dir->sync_seq,
+ DIRECTOR_VERSION_MINOR);
}
if (conn->to_ping != NULL)
timeout_remove(&conn->to_ping);
@@ -693,16 +687,22 @@
static void
director_connection_sync_host(struct director_connection *conn,
struct director_host *host,
- uint32_t seq, const char *line)
+ uint32_t seq, unsigned int minor_version)
{
struct director *dir = conn->dir;
+ if (minor_version > DIRECTOR_VERSION_MINOR) {
+ /* we're not up to date */
+ minor_version = DIRECTOR_VERSION_MINOR;
+ }
+
if (host->self) {
if (dir->sync_seq != seq) {
/* stale SYNC event */
return;
}
+ dir->synced_minor_version = minor_version;
if (!dir->ring_handshaked) {
/* the ring is handshaked */
director_set_ring_handshaked(dir);
@@ -716,35 +716,36 @@
}
director_set_ring_synced(dir);
}
- } else {
+ } else if (dir->right != NULL) {
/* forward it to the connection on right */
- if (dir->right != NULL) {
- director_connection_send(dir->right,
- t_strconcat(line, "\n", NULL));
- }
+ director_sync_send(dir, host, seq, minor_version);
}
}
static bool director_connection_sync(struct director_connection *conn,
- const char *const *args, const char *line)
+ const char *const *args)
{
struct director *dir = conn->dir;
struct director_host *host;
struct ip_addr ip;
- unsigned int port, seq;
+ unsigned int port, seq, minor_version = 0;
- if (str_array_length(args) != 3 ||
+ if (str_array_length(args) < 3 ||
!director_args_parse_ip_port(conn, args, &ip, &port) ||
str_to_uint(args[2], &seq) < 0) {
i_error("director(%s): Invalid SYNC args", conn->name);
return FALSE;
}
+ if (args[3] != NULL)
+ minor_version = atoi(args[3]);
/* 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)
- director_connection_sync_host(conn, host, seq, line);
+ if (host != NULL) {
+ director_connection_sync_host(conn, host, seq,
+ minor_version);
+ }
if (host == NULL || !host->self)
director_resend_sync(dir);
@@ -866,7 +867,7 @@
if (strcmp(cmd, "DIRECTOR") == 0)
return director_cmd_director(conn, args);
if (strcmp(cmd, "SYNC") == 0)
- return director_connection_sync(conn, args, line);
+ return director_connection_sync(conn, args);
if (strcmp(cmd, "CONNECT") == 0)
return director_cmd_connect(conn, args);
diff -r 94de7605f50f -r 334424e7465e src/director/director.c
--- a/src/director/director.c Wed Mar 07 16:58:37 2012 +0200
+++ b/src/director/director.c Wed Mar 07 20:16:33 2012 +0200
@@ -155,6 +155,7 @@
it must have failed recently */
director_connection_deinit(&dir->left);
}
+ dir->synced_minor_version = DIRECTOR_VERSION_MINOR;
if (!dir->ring_handshaked)
director_set_ring_handshaked(dir);
else
@@ -232,14 +233,27 @@
director_set_state_changed(dir);
}
+void director_sync_send(struct director *dir, struct director_host *host,
+ uint32_t seq, unsigned int minor_version)
+{
+ string_t *str = t_str_new(128);
+
+ str_printfa(str, "SYNC\t%s\t%u\t%u",
+ net_ip2addr(&host->ip), host->port, seq);
+ if (minor_version > 0) {
+ /* only minor_version>0 supports this parameter */
+ str_printfa(str, "\t%u", minor_version);
+ }
+ str_append_c(str, '\n');
+ director_connection_send(dir->right, str_c(str));
+}
+
bool director_resend_sync(struct director *dir)
{
if (!dir->ring_synced && dir->left != NULL && dir->right != NULL) {
/* send a new SYNC in case the previous one got dropped */
- director_connection_send(dir->right,
- t_strdup_printf("SYNC\t%s\t%u\t%u\n",
- net_ip2addr(&dir->self_ip),
- dir->self_port, dir->sync_seq));
+ director_sync_send(dir, dir->self_host, dir->sync_seq,
+ DIRECTOR_VERSION_MINOR);
if (dir->to_sync != NULL)
timeout_reset(dir->to_sync);
return TRUE;
@@ -295,9 +309,8 @@
if (dir->left != NULL)
director_connection_wait_sync(dir->left);
director_connection_wait_sync(dir->right);
- director_connection_send(dir->right, t_strdup_printf(
- "SYNC\t%s\t%u\t%u\n", net_ip2addr(&dir->self_ip),
- dir->self_port, dir->sync_seq));
+ director_sync_send(dir, dir->self_host, dir->sync_seq,
+ DIRECTOR_VERSION_MINOR);
}
void director_sync_freeze(struct director *dir)
diff -r 94de7605f50f -r 334424e7465e src/director/director.h
--- a/src/director/director.h Wed Mar 07 16:58:37 2012 +0200
+++ b/src/director/director.h Wed Mar 07 20:16:33 2012 +0200
@@ -4,6 +4,10 @@
#include "network.h"
#include "director-settings.h"
+#define DIRECTOR_VERSION_NAME "director"
+#define DIRECTOR_VERSION_MAJOR 1
+#define DIRECTOR_VERSION_MINOR 0
+
struct director;
struct mail_host;
struct user;
@@ -46,6 +50,8 @@
struct ipc_client *ipc_proxy;
unsigned int sync_seq;
+ /* the lowest minor version supported by the ring */
+ unsigned int synced_minor_version;
time_t ring_last_sync_time;
/* director ring handshaking is complete.
@@ -76,6 +82,8 @@
void director_set_ring_synced(struct director *dir);
void director_set_ring_unsynced(struct director *dir);
void director_set_state_changed(struct director *dir);
+void director_sync_send(struct director *dir, struct director_host *host,
+ uint32_t seq, unsigned int minor_version);
bool director_resend_sync(struct director *dir);
void director_update_host(struct director *dir, struct director_host *src,
More information about the dovecot-cvs
mailing list