Mercurial > dovecot > core-2.2
diff src/director/doveadm-connection.c @ 14571:42cca8a1d179
director: Implemented ability to remove directors from a running ring.
Also added doveadm command for adding a new director to a running ring.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 19 May 2012 21:18:04 +0300 |
parents | fc8031c5e691 |
children | ca37d1577291 |
line wrap: on
line diff
--- a/src/director/doveadm-connection.c Sat May 19 21:16:42 2012 +0300 +++ b/src/director/doveadm-connection.c Sat May 19 21:18:04 2012 +0300 @@ -109,7 +109,9 @@ right = dir->right != NULL && director_connection_get_host(dir->right) == host; - if (dir->self_host == host) + if (host->removed) + type = "removed"; + else if (dir->self_host == host) type = "self"; else if (left) type = right ? "l+r" : "left"; @@ -129,6 +131,58 @@ } static bool +doveadm_cmd_director_add(struct doveadm_connection *conn, const char *line) +{ + const char *const *args; + struct director_host *host; + struct ip_addr ip; + unsigned int port = conn->dir->self_port; + + args = t_strsplit_tab(line); + if (args[0] == NULL || + net_addr2ip(line, &ip) < 0 || + (args[1] != NULL && str_to_uint(args[1], &port) < 0)) { + i_error("doveadm sent invalid DIRECTOR-ADD parameters"); + return FALSE; + } + + if (director_host_lookup(conn->dir, &ip, port) == NULL) { + host = director_host_add(conn->dir, &ip, port); + director_notify_ring_added(host, conn->dir->self_host); + } + o_stream_send(conn->output, "OK\n", 3); + return TRUE; +} + +static bool +doveadm_cmd_director_remove(struct doveadm_connection *conn, const char *line) +{ + const char *const *args; + struct director_host *host; + struct ip_addr ip; + unsigned int port = 0; + + args = t_strsplit_tab(line); + if (args[0] == NULL || + net_addr2ip(line, &ip) < 0 || + (args[1] != NULL && str_to_uint(args[1], &port) < 0)) { + i_error("doveadm sent invalid DIRECTOR-REMOVE parameters"); + return FALSE; + } + + host = port != 0 ? + director_host_lookup(conn->dir, &ip, port) : + director_host_lookup_ip(conn->dir, &ip); + if (host == NULL) + o_stream_send_str(conn->output, "NOTFOUND\n"); + else { + director_ring_remove(host, conn->dir->self_host); + o_stream_send(conn->output, "OK\n", 3); + } + return TRUE; +} + +static bool doveadm_cmd_host_set(struct doveadm_connection *conn, const char *line) { struct director *dir = conn->dir; @@ -364,6 +418,10 @@ doveadm_cmd_host_list_removed(conn); else if (strcmp(cmd, "DIRECTOR-LIST") == 0) doveadm_cmd_director_list(conn); + else if (strcmp(cmd, "DIRECTOR-ADD") == 0) + doveadm_cmd_director_add(conn, args); + else if (strcmp(cmd, "DIRECTOR-REMOVE") == 0) + doveadm_cmd_director_remove(conn, args); else if (strcmp(cmd, "HOST-SET") == 0) ret = doveadm_cmd_host_set(conn, args); else if (strcmp(cmd, "HOST-REMOVE") == 0)