Mercurial > dovecot > core-2.2
diff src/director/doveadm-connection.c @ 18067:a7e830b9b967
director: Added support for backend cluster "tags".
This allows using a single director ring for multiple backend clusters. By
default everything has an empty tag. A passdb lookup can return
"director_tag" field containing the wanted tag name. If there aren't any
backend servers with the wanted tag, it's treated the same as if there
aren't any backend servers available (= wait for 30 secs for a backend and
then return temporary failure).
Tags can be added to configuration by adding @tag suffix to IPs/hosts. For
example:
director_mail_servers = 10.0.0.100-10.0.0.110@name1 10.0.0.120@name2
"doveadm director add" can also add tags either with @tag suffix or with -t
parameter. "doveadm director status user@domain" requires giving the user's
correct tag with -t parameter or the results won't be correct (empty tag's
results are shown). Tags can't currently be changed for an existing host
without removing it first.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 12 Nov 2014 06:58:37 +0200 |
parents | b9df3d654710 |
children | 3009a1a6f6d5 |
line wrap: on
line diff
--- a/src/director/doveadm-connection.c Wed Nov 12 06:46:45 2014 +0200 +++ b/src/director/doveadm-connection.c Wed Nov 12 06:58:37 2014 +0200 @@ -7,6 +7,7 @@ #include "ostream.h" #include "array.h" #include "str.h" +#include "strescape.h" #include "llist.h" #include "master-service.h" #include "user-directory.h" @@ -46,9 +47,11 @@ string_t *str = t_str_new(1024); array_foreach(mail_hosts_get(conn->dir->mail_hosts), hostp) { - str_printfa(str, "%s\t%u\t%u\n", + str_printfa(str, "%s\t%u\t%u\t", net_ip2addr(&(*hostp)->ip), (*hostp)->vhost_count, (*hostp)->user_count); + str_append_tabescaped(str, (*hostp)->tag); + str_append_c(str, '\n'); } str_append_c(str, '\n'); o_stream_nsend(conn->output, str_data(str), str_len(str)); @@ -244,14 +247,21 @@ doveadm_cmd_host_set(struct doveadm_connection *conn, const char *line) { struct director *dir = conn->dir; - const char *const *args; + const char *const *args, *ip_str, *tag = ""; struct mail_host *host; struct ip_addr ip; unsigned int vhost_count = UINT_MAX; args = t_strsplit_tab(line); - if (args[0] == NULL || - net_addr2ip(args[0], &ip) < 0 || + ip_str = args[0]; + if (ip_str != NULL) { + tag = strchr(ip_str, '@'); + if (tag == NULL) + tag = ""; + else + ip_str = t_strdup_until(ip_str, tag++); + } + if (ip_str == NULL || net_addr2ip(ip_str, &ip) < 0 || (args[1] != NULL && str_to_uint(args[1], &vhost_count) < 0)) { i_error("doveadm sent invalid HOST-SET parameters: %s", line); return FALSE; @@ -262,9 +272,12 @@ } host = mail_host_lookup(dir->mail_hosts, &ip); if (host == NULL) - host = mail_host_add_ip(dir->mail_hosts, &ip); + host = mail_host_add_ip(dir->mail_hosts, &ip, tag); if (vhost_count != UINT_MAX) mail_host_set_vhost_count(dir->mail_hosts, host, vhost_count); + /* NOTE: we don't supporting changing a tag for an existing host. + it needs to be removed first. otherwise it would be a bit ugly to + handle. */ director_update_host(dir, dir->self_host, NULL, host); o_stream_nsend(conn->output, "OK\n", 3); @@ -340,10 +353,19 @@ { struct user *user; struct mail_host *host; + const char *username, *tag, *const *args; unsigned int username_hash; string_t *str = t_str_new(256); - if (str_to_uint(line, &username_hash) < 0) + args = t_strsplit_tab(line); + if (args[0] == NULL) { + username = ""; + tag = ""; + } else { + username = args[0]; + tag = args[1] != NULL ? args[1] : ""; + } + if (str_to_uint(username, &username_hash) < 0) username_hash = user_directory_get_username_hash(conn->dir->users, line); /* get user's current host */ @@ -357,7 +379,7 @@ } /* get host if it wasn't in user directory */ - host = mail_host_get_by_hash(conn->dir->mail_hosts, username_hash); + host = mail_host_get_by_hash(conn->dir->mail_hosts, username_hash, tag); if (host == NULL) str_append(str, "\t"); else @@ -365,7 +387,7 @@ /* get host with default configuration */ host = mail_host_get_by_hash(conn->dir->orig_config_hosts, - username_hash); + username_hash, tag); if (host == NULL) str_append(str, "\t"); else