Skip to content

Commit

Permalink
director: Make sure USER-KILLED isn't sent before USER-MOVE
Browse files Browse the repository at this point in the history
If USER-MOVE was for a user that didn't exist, killing sent USER-KILLED
immediately before the forwarding USER-MOVE. This caused the move to get
stuck, giving errors like:

director: Error: Finishing user 3224731354 move timed out, its state may now be inconsistent (state=waiting-for-everyone)
  • Loading branch information
sirainen committed Jan 24, 2017
1 parent 30d3f03 commit 8f4bd3b
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/director/director.c
Expand Up @@ -1029,6 +1029,7 @@ void director_move_user(struct director *dir, struct director_host *src,
unsigned int username_hash, struct mail_host *host)
{
struct user_directory *users = host->tag->users;
struct mail_host *old_host = NULL;
struct user *user;

/* 1. move this user's host, and set its "killing" flag to delay all of
Expand All @@ -1051,10 +1052,7 @@ void director_move_user(struct director *dir, struct director_host *src,
if (user == NULL) {
user = user_directory_add(users, username_hash,
host, ioloop_time);
director_kill_user(dir, src, user, host->tag, NULL);
} else {
struct mail_host *old_host = user->host;

if (user->host == host) {
/* user is already in this host */
return;
Expand All @@ -1063,11 +1061,11 @@ void director_move_user(struct director *dir, struct director_host *src,
the old tag has to be the same. */
i_assert(user->host->tag == host->tag);

old_host = user->host;
user->host->user_count--;
user->host = host;
user->host->user_count++;
user->timestamp = ioloop_time;
director_kill_user(dir, src, user, old_host->tag, old_host);
}

if (orig_src == NULL) {
Expand All @@ -1078,6 +1076,9 @@ void director_move_user(struct director *dir, struct director_host *src,
"USER-MOVE\t%s\t%u\t%u\t%u\t%s\n",
net_ip2addr(&orig_src->ip), orig_src->port, orig_src->last_seq,
user->username_hash, net_ip2addr(&user->host->ip)));
/* kill the user only after sending the USER-MOVE, because the kill
may finish instantly. */
director_kill_user(dir, src, user, host->tag, old_host);
}

static void
Expand Down

0 comments on commit 8f4bd3b

Please sign in to comment.