director_cmd_host_int(struct director_connection *conn, const char *const *args,
struct director_host *dir_host)
{
+ struct director_host *src_host = conn->host;
struct mail_host *host;
struct ip_addr ip;
const char *tag = "";
mail_host_set_tag(host, tag);
update = TRUE;
}
+ if (update && host->desynced) {
+ vhost_count = I_MIN(vhost_count, host->vhost_count);
+ if (host->down != down) {
+ if (host->last_updown_change <= last_updown_change)
+ down = host->last_updown_change;
+ }
+ last_updown_change = I_MAX(last_updown_change,
+ host->last_updown_change);
+ i_warning("director(%s): Host %s is being updated before previous update had finished - "
+ "setting to state=%s vhosts=%u",
+ conn->name, net_ip2addr(&host->ip),
+ down ? "down" : "up", vhost_count);
+ /* make the change appear to come from us, so it
+ reaches the full ring */
+ dir_host = NULL;
+ src_host = conn->dir->self_host;
+ }
}
if (update) {
down, last_updown_change);
mail_host_set_vhost_count(conn->dir->mail_hosts,
host, vhost_count);
- director_update_host(conn->dir, conn->host, dir_host, host);
+ director_update_host(conn->dir, src_host, dir_host, host);
}
return TRUE;
}
timeout_remove(&dir->to_sync);
dir->ring_synced = TRUE;
dir->ring_last_sync_time = ioloop_time;
+ mail_hosts_set_synced(dir->mail_hosts);
director_set_state_changed(dir);
}
}
str_append_c(str, '\n');
director_update_send(dir, src, str_c(str));
+
+ host->desynced = TRUE;
director_sync(dir);
}
return mail_host_get_by_hash_direct(list, hash, tag);
}
+void mail_hosts_set_synced(struct mail_host_list *list)
+{
+ struct mail_host *const *hostp;
+
+ array_foreach(&list->hosts, hostp)
+ (*hostp)->desynced = FALSE;
+}
+
bool mail_hosts_have_usable(struct mail_host_list *list)
{
if (list->hosts_unsorted)
struct ip_addr ip;
char *tag;
+
+ /* host was recently changed and ring hasn't synced yet since */
+ unsigned int desynced:1;
};
ARRAY_DEFINE_TYPE(mail_host, struct mail_host *);
unsigned int vhost_count);
void mail_host_remove(struct mail_host_list *list, struct mail_host *host);
+void mail_hosts_set_synced(struct mail_host_list *list);
bool mail_hosts_have_usable(struct mail_host_list *list);
const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list);