dovecot-2.0: Added doveadm director flush command for dropping u...

dovecot at dovecot.org dovecot at dovecot.org
Thu May 20 14:35:42 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/ef1de95396d4
changeset: 11355:ef1de95396d4
user:      Timo Sirainen <tss at iki.fi>
date:      Thu May 20 13:35:38 2010 +0200
description:
Added doveadm director flush command for dropping user associations from memory.
This should probably mainly be used for testing.

diffstat:

 src/director/director-connection.c |  21 ++++++++++
 src/director/director.c            |   8 ++++
 src/director/director.h            |   2 +
 src/director/doveadm-connection.c  |  66 ++++++++++++++++++++++++++++-----
 src/doveadm/doveadm-director.c     |  65 ++++++++++++++++++++++++++++++++-
 5 files changed, 151 insertions(+), 11 deletions(-)

diffs (248 lines):

diff -r f70433791464 -r ef1de95396d4 src/director/director-connection.c
--- a/src/director/director-connection.c	Thu May 20 13:17:30 2010 +0200
+++ b/src/director/director-connection.c	Thu May 20 13:35:38 2010 +0200
@@ -317,6 +317,25 @@
 	return TRUE;
 }
 
+static bool
+director_cmd_host_flush(struct director_connection *conn,
+			 const char *const *args)
+{
+	struct mail_host *host;
+	struct ip_addr ip;
+
+	if (str_array_length(args) != 1 ||
+	    net_addr2ip(args[0], &ip) < 0) {
+		i_error("director(%s): Invalid HOST-FLUSH args", conn->name);
+		return FALSE;
+	}
+
+	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
+	if (host != NULL)
+		director_flush_host(conn->dir, conn->host, host);
+	return TRUE;
+}
+
 static void director_handshake_cmd_done(struct director_connection *conn)
 {
 	struct director *dir = conn->dir;
@@ -513,6 +532,8 @@
 		return director_cmd_host(conn, args);
 	if (strcmp(cmd, "HOST-REMOVE") == 0)
 		return director_cmd_host_remove(conn, args);
+	if (strcmp(cmd, "HOST-FLUSH") == 0)
+		return director_cmd_host_flush(conn, args);
 	if (strcmp(cmd, "DIRECTOR") == 0)
 		return director_cmd_director(conn, args);
 	if (strcmp(cmd, "SYNC") == 0)
diff -r f70433791464 -r ef1de95396d4 src/director/director.c
--- a/src/director/director.c	Thu May 20 13:17:30 2010 +0200
+++ b/src/director/director.c	Thu May 20 13:35:38 2010 +0200
@@ -150,6 +150,14 @@
 	mail_host_remove(dir->mail_hosts, host);
 }
 
+void director_flush_host(struct director *dir, struct director_host *src,
+			 struct mail_host *host)
+{
+	director_update_send(dir, src, t_strdup_printf(
+		"HOST-FLUSH\t%s\n", net_ip2addr(&host->ip)));
+	user_directory_remove_host(dir->users, host);
+}
+
 void director_update_user(struct director *dir, struct director_host *src,
 			  struct user *user)
 {
diff -r f70433791464 -r ef1de95396d4 src/director/director.h
--- a/src/director/director.h	Thu May 20 13:17:30 2010 +0200
+++ b/src/director/director.h	Thu May 20 13:35:38 2010 +0200
@@ -81,6 +81,8 @@
 			  struct mail_host *host);
 void director_remove_host(struct director *dir, struct director_host *src,
 			  struct mail_host *host);
+void director_flush_host(struct director *dir, struct director_host *src,
+			 struct mail_host *host);
 void director_update_user(struct director *dir, struct director_host *src,
 			  struct user *user);
 
diff -r f70433791464 -r ef1de95396d4 src/director/doveadm-connection.c
--- a/src/director/doveadm-connection.c	Thu May 20 13:17:30 2010 +0200
+++ b/src/director/doveadm-connection.c	Thu May 20 13:35:38 2010 +0200
@@ -103,7 +103,7 @@
 	struct ip_addr ip;
 
 	if (net_addr2ip(line, &ip) < 0) {
-		i_error("doveadm sent invalid HOST-SET parameters");
+		i_error("doveadm sent invalid HOST-REMOVE parameters");
 		return FALSE;
 	}
 	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
@@ -116,6 +116,41 @@
 	return TRUE;
 }
 
+static void
+doveadm_cmd_host_flush_all(struct doveadm_connection *conn)
+{
+	struct mail_host *const *hostp;
+
+	array_foreach(mail_hosts_get(conn->dir->mail_hosts), hostp)
+		director_flush_host(conn->dir, conn->dir->self_host, *hostp);
+	o_stream_send(conn->output, "OK\n", 3);
+}
+
+static bool
+doveadm_cmd_host_flush(struct doveadm_connection *conn, const char *line)
+{
+	struct mail_host *host;
+	struct ip_addr ip;
+
+	if (*line == '\0') {
+		doveadm_cmd_host_flush_all(conn);
+		return TRUE;
+	}
+
+	if (net_addr2ip(line, &ip) < 0) {
+		i_error("doveadm sent invalid HOST-FLUSH parameters");
+		return FALSE;
+	}
+	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
+	if (host == NULL)
+		o_stream_send_str(conn->output, "NOTFOUND\n");
+	else {
+		director_flush_host(conn->dir, conn->dir->self_host, host);
+		o_stream_send(conn->output, "OK\n", 3);
+	}
+	return TRUE;
+}
+
 static bool
 doveadm_cmd_user_lookup(struct doveadm_connection *conn, const char *line)
 {
@@ -156,7 +191,7 @@
 
 static void doveadm_connection_input(struct doveadm_connection *conn)
 {
-	const char *line;
+	const char *line, *cmd, *args;
 	bool ret = TRUE;
 
 	if (!conn->handshaked) {
@@ -174,16 +209,27 @@
 	}
 
 	while ((line = i_stream_read_next_line(conn->input)) != NULL && ret) {
-		if (strcmp(line, "HOST-LIST") == 0)
+		args = strchr(line, '\t');
+		if (args == NULL) {
+			cmd = line;
+			args = "";
+		} else {
+			cmd = t_strdup_until(line, args);
+			args++;
+		}
+
+		if (strcmp(cmd, "HOST-LIST") == 0)
 			doveadm_cmd_host_list(conn);
-		else if (strcmp(line, "DIRECTOR-LIST") == 0)
+		else if (strcmp(cmd, "DIRECTOR-LIST") == 0)
 			doveadm_cmd_director_list(conn);
-		else if (strncmp(line, "HOST-SET\t", 9) == 0)
-			ret = doveadm_cmd_host_set(conn, line + 9);
-		else if (strncmp(line, "HOST-REMOVE\t", 12) == 0)
-			ret = doveadm_cmd_host_remove(conn, line + 12);
-		else if (strncmp(line, "USER-LOOKUP\t", 12) == 0)
-			ret = doveadm_cmd_user_lookup(conn, line + 12);
+		else if (strcmp(cmd, "HOST-SET") == 0)
+			ret = doveadm_cmd_host_set(conn, args);
+		else if (strcmp(cmd, "HOST-REMOVE") == 0)
+			ret = doveadm_cmd_host_remove(conn, args);
+		else if (strcmp(cmd, "HOST-FLUSH") == 0)
+			ret = doveadm_cmd_host_flush(conn, args);
+		else if (strcmp(cmd, "USER-LOOKUP") == 0)
+			ret = doveadm_cmd_user_lookup(conn, args);
 		else {
 			i_error("doveadm sent unknown command: %s", line);
 			ret = FALSE;
diff -r f70433791464 -r ef1de95396d4 src/doveadm/doveadm-director.c
--- a/src/doveadm/doveadm-director.c	Thu May 20 13:17:30 2010 +0200
+++ b/src/doveadm/doveadm-director.c	Thu May 20 13:35:38 2010 +0200
@@ -225,13 +225,76 @@
 	director_disconnect(ctx);
 }
 
+static void cmd_director_flush_all(struct director_context *ctx)
+{
+	const char *line;
+
+	director_send(ctx, "HOST-FLUSH\n");
+
+	line = i_stream_read_next_line(ctx->input);
+	if (line == NULL)
+		fprintf(stderr, "failed\n");
+	else if (strcmp(line, "OK") != 0)
+		fprintf(stderr, "%s\n", line);
+	else if (doveadm_verbose)
+		printf("flushed\n");
+	director_disconnect(ctx);
+}
+
+static void cmd_director_flush(int argc, char *argv[])
+{
+	struct director_context *ctx;
+	struct ip_addr *ips;
+	unsigned int i, ips_count;
+	struct ip_addr ip;
+	const char *host, *line;
+
+	ctx = cmd_director_init(argc, argv, 0);
+	host = argv[optind++];
+	if (host == NULL || argv[optind] != NULL)
+		help(&doveadm_cmd_director[2]);
+
+	if (strcmp(host, "all") == 0) {
+		cmd_director_flush_all(ctx);
+		return;
+	}
+	if (net_addr2ip(host, &ip) == 0) {
+		ips = &ip;
+		ips_count = 1;
+	} else {
+		if (net_gethostbyname(host, &ips, &ips_count) < 0)
+			i_fatal("gethostname(%s) failed: %m", host);
+	}
+
+	for (i = 0; i < ips_count; i++) {
+		director_send(ctx,
+			t_strdup_printf("HOST-FLUSH\t%s\n", net_ip2addr(&ip)));
+	}
+	for (i = 0; i < ips_count; i++) {
+		line = i_stream_read_next_line(ctx->input);
+		if (line == NULL || strcmp(line, "OK") != 0) {
+			fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
+				line == NULL ? "failed" :
+				(strcmp(line, "NOTFOUND") == 0 ?
+				 "doesn't exist" : line));
+		} else if (doveadm_verbose) {
+			printf("%s: flushed\n", net_ip2addr(&ips[i]));
+		}
+	}
+	if (i != ips_count)
+		i_fatal("director flush failed");
+	director_disconnect(ctx);
+}
+
 struct doveadm_cmd doveadm_cmd_director[] = {
 	{ cmd_director_status, "director status",
 	  "[-a <director socket path>] [<username>]", NULL },
 	{ cmd_director_add, "director add",
 	  "[-a <director socket path>] <host> [<vhost count>]", NULL },
 	{ cmd_director_remove, "director remove",
-	  "[-a <director socket path>] <host>", NULL }
+	  "[-a <director socket path>] <host>", NULL },
+	{ cmd_director_flush, "director flush",
+	  "[-a <director socket path>] <host>|all", NULL }
 };
 
 


More information about the dovecot-cvs mailing list