From: Timo Sirainen Date: Wed, 4 Oct 2017 12:39:08 +0000 (+0300) Subject: director: Fix tracking user move count when user is freed early X-Git-Tag: 2.3.0.rc1~937 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=34642ccff3ad4906cd365d0cb3deaa1e4f16610b;p=thirdparty%2Fdovecot%2Fcore.git director: Fix tracking user move count when user is freed early users_moving_count wasn't updated if the user was freed before killing it finished. This caused "doveadm director flush" to hang while waiting for the move count to drop to 0, which it never did. Also following flushes were doing less work in parallel, or possibly even nothing since director thought there were too many users already being moved. --- diff --git a/src/director/director.c b/src/director/director.c index b7049c796e..423e941ed9 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -857,6 +857,14 @@ director_flush_user(struct director *dir, struct user *user) program_client_run_async(ctx->pclient, director_flush_user_continue, ctx); } +static void director_user_move_finished(struct director *dir) +{ + i_assert(dir->users_moving_count > 0); + dir->users_moving_count--; + + director_set_state_changed(dir); +} + static void director_user_move_free(struct user *user) { struct director *dir = user->kill_ctx->dir; @@ -872,10 +880,7 @@ static void director_user_move_free(struct user *user) i_free(kill_ctx); user->kill_ctx = NULL; - i_assert(dir->users_moving_count > 0); - dir->users_moving_count--; - - director_set_state_changed(dir); + director_user_move_finished(dir); } static void @@ -971,6 +976,7 @@ static void director_kill_user_callback(enum ipc_client_cmd_state state, if (!DIRECTOR_KILL_CONTEXT_IS_VALID(user, ctx)) { /* user was already freed - ignore */ i_assert(ctx->to_move == NULL); + director_user_move_finished(ctx->dir); i_free(ctx); } else { i_assert(ctx->kill_state == USER_KILL_STATE_KILLING ||