changeset 22552:7b8e95de2bff

director: Fix HOST-RESET-USERS when all hosts are down 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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 04 Oct 2017 15:41:03 +0300
parents a89fc39f2135
children 7db517071db5
files src/director/doveadm-connection.c
diffstat 1 files changed, 11 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/director/doveadm-connection.c	Wed Oct 04 15:39:08 2017 +0300
+++ b/src/director/doveadm-connection.c	Wed Oct 04 15:41:03 2017 +0300
@@ -49,6 +49,7 @@
 	struct director_user_iter *iter;
 	unsigned int host_idx, hosts_count;
 	unsigned int max_moving_users;
+	bool users_killed;
 };
 
 struct doveadm_connection {
@@ -489,7 +490,6 @@
 	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;
@@ -497,8 +497,10 @@
 	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)
@@ -517,18 +519,19 @@
 				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);