Mercurial > dovecot > original-hg > dovecot-2.1
changeset 14985:966a9ee85d58
director: Fixes to handling users near expiration.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 29 Jul 2013 22:10:49 +0300 |
parents | a34c9e40d473 |
children | 15537f882a0b |
files | src/director/director-connection.c |
diffstat | 1 files changed, 38 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/director/director-connection.c Mon Jul 29 22:10:01 2013 +0300 +++ b/src/director/director-connection.c Mon Jul 29 22:10:49 2013 +0300 @@ -476,7 +476,24 @@ dir_debug("user refresh: %u set weak", username_hash); user->weak = TRUE; ret = TRUE; - } else if (user->host != host) { + } else if (weak) { + dir_debug("user refresh: %u weak update to %s ignored, " + "we recently changed it to %s", + username_hash, net_ip2addr(&host->ip), + net_ip2addr(&user->host->ip)); + host = user->host; + ret = TRUE; + } else if (user->host == host) { + /* update to the same host */ + } else if (user_directory_user_is_near_expiring(dir->users, user)) { + /* host conflict for a user that is already near expiring. we can + assume that the other director had already dropped this user + and we should have as well. use the new host. */ + dir_debug("user refresh: %u is nearly expired, " + "replacing host %s with %s", username_hash, + net_ip2addr(&user->host->ip), net_ip2addr(&host->ip)); + ret = TRUE; + } else { /* non-weak user received a non-weak update with conflicting host. this shouldn't happen. */ string_t *str = t_str_new(128); @@ -709,11 +726,11 @@ ourself. */ *host_r = NULL; } else { + *host_r = host; if (seq <= host->last_seq) { /* already seen this */ return 1; } - *host_r = host; host->last_seq = seq; } return 0; @@ -729,7 +746,7 @@ struct mail_host *host; struct user *user; struct director_host *src_host = conn->host; - bool weak = TRUE; + bool weak = TRUE, weak_forward = FALSE; int ret; /* note that unlike other commands we don't want to just ignore @@ -750,15 +767,28 @@ return TRUE; } - if (ret > 0) { - /* The entire ring has seen this USER-WEAK. - make it non-weak now. */ + if (ret == 0) + ; + else if (dir_host == conn->dir->self_host) { + /* We originated this USER-WEAK request. The entire ring has seen + it and there weren't any conflicts. Make the user non-weak. */ + dir_debug("user refresh: %u Our USER-WEAK seen by the entire ring", + username_hash); + src_host = conn->dir->self_host; weak = FALSE; - src_host = conn->dir->self_host; + } else { + /* The original USER-WEAK sender will send a new non-weak USER + update saying what really happened. We'll still need to forward + this around the ring to the origin so it also knows it has + travelled through the ring. */ + dir_debug("user refresh: %u Remote USER-WEAK from %s seen by the entire ring, ignoring", + username_hash, net_ip2addr(&dir_host->ip)); + weak_forward = TRUE; } if (director_user_refresh(conn, username_hash, - host, ioloop_time, weak, &user)) { + host, ioloop_time, weak, &user) || + weak_forward) { if (!user->weak) director_update_user(conn->dir, src_host, user); else {