]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added doveadm director flush command for dropping user associations from memory.
authorTimo Sirainen <tss@iki.fi>
Thu, 20 May 2010 11:35:38 +0000 (13:35 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 20 May 2010 11:35:38 +0000 (13:35 +0200)
This should probably mainly be used for testing.

--HG--
branch : HEAD

src/director/director-connection.c
src/director/director.c
src/director/director.h
src/director/doveadm-connection.c
src/doveadm/doveadm-director.c

index a416c98cf41de316ae274221f02db55802f235ae..5de7be91c48d9ef22af209c281c90a27aaa294a5 100644 (file)
@@ -317,6 +317,25 @@ director_cmd_host_remove(struct director_connection *conn,
        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 @@ director_connection_handle_line(struct director_connection *conn,
                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)
index d938e9da94eb2481770a0367be8c444a094dca19..9a19eaacbffcb1a52d76389f540fc69cc6fde006 100644 (file)
@@ -150,6 +150,14 @@ void director_remove_host(struct director *dir, struct director_host *src,
        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)
 {
index fcfd19960ffba2a9ef2fce68d602bd0883b6326b..dd65931fd5c04143b3d9dd6e644142a67d4bdef6 100644 (file)
@@ -81,6 +81,8 @@ void director_update_host(struct director *dir, struct director_host *src,
                          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);
 
index 28f8d7e52ab3552c8b18293daf90da512232c088..6ee4c1509214c0582d0efd1fc7b48eec80a31311 100644 (file)
@@ -103,7 +103,7 @@ doveadm_cmd_host_remove(struct doveadm_connection *conn, const char *line)
        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 @@ doveadm_cmd_host_remove(struct doveadm_connection *conn, const char *line)
        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 @@ doveadm_cmd_user_lookup(struct doveadm_connection *conn, const char *line)
 
 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 @@ static void doveadm_connection_input(struct doveadm_connection *conn)
        }
 
        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;
index 988e3746e6d65cee6c8a7aa5b605864fe30bfef8..a90815efa1c83d25faaf02bb407f53282c03cd69 100644 (file)
@@ -225,13 +225,76 @@ static void cmd_director_remove(int argc, char *argv[])
        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 }
 };