]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Fix HOST-RESET-USERS when all hosts are down
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 4 Oct 2017 12:41:03 +0000 (15:41 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 4 Oct 2017 12:52:24 +0000 (15:52 +0300)
If there were a lot of users being kicked, the host was flushed after the
initial round of user kills. This caused the rest of the user connections to
be just discarded instead of actually being killed.

src/director/doveadm-connection.c

index 0ed43882d65993b53b194310b498cb17bd76956f..570ea7e38bbb356d09597faf25bb3af1b429c2bc 100644 (file)
@@ -49,6 +49,7 @@ struct director_reset_cmd {
        struct director_user_iter *iter;
        unsigned int host_idx, hosts_count;
        unsigned int max_moving_users;
+       bool users_killed;
 };
 
 struct doveadm_connection {
@@ -486,7 +487,6 @@ director_host_reset_users(struct director_reset_cmd *cmd,
        struct director *dir = cmd->dir;
        struct user *user;
        struct mail_host *new_host;
-       bool users_killed = FALSE;
 
        if (dir->users_moving_count >= cmd->max_moving_users)
                return FALSE;
@@ -494,8 +494,10 @@ director_host_reset_users(struct director_reset_cmd *cmd,
        if (dir->right != NULL)
                director_connection_cork(dir->right);
 
-       if (cmd->iter == NULL)
+       if (cmd->iter == NULL) {
                cmd->iter = director_iterate_users_init(dir);
+               cmd->users_killed = FALSE;
+       }
 
        while ((user = director_iterate_users_next(cmd->iter)) != NULL) {
                if (user->host != host)
@@ -514,18 +516,19 @@ director_host_reset_users(struct director_reset_cmd *cmd,
                                director_kill_user(dir, dir->self_host, user,
                                                   user->host->tag, user->host,
                                                   TRUE);
-                               users_killed = TRUE;
+                               cmd->users_killed = TRUE;
                        }
                } T_END;
                if (dir->users_moving_count >= cmd->max_moving_users)
                        break;
        }
-       if (user == NULL)
+       if (user == NULL) {
                director_iterate_users_deinit(&cmd->iter);
-       if (users_killed) {
-               /* no more backends. we already sent kills. now remove the
-                  users entirely from the host. */
-               director_flush_host(dir, dir->self_host, NULL, host);
+               if (cmd->users_killed) {
+                       /* no more backends. we already sent kills. now remove
+                          the users entirely from the host. */
+                       director_flush_host(dir, dir->self_host, NULL, host);
+               }
        }
        if (dir->right != NULL)
                director_connection_uncork(dir->right);