From: Timo Sirainen Date: Thu, 5 Oct 2017 08:51:23 +0000 (+0300) Subject: director: Allow doveadm director ring remove for the same director X-Git-Tag: 2.3.0.rc1~910 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b0421c7397be2146988ee3afb5dcc491c01206cc;p=thirdparty%2Fdovecot%2Fcore.git director: Allow doveadm director ring remove for the same director Fixes: Panic: file doveadm-connection.c: line 859 (doveadm_connection_cmd_run): assertion failed: (conn->dir->right == NULL && conn->dir->left == NULL) --- diff --git a/src/director/director.c b/src/director/director.c index 423e941ed9..650fa05d9d 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -527,19 +527,22 @@ void director_ring_remove(struct director_host *removed_host, i_info("Removing director %s from ring (requested by %s)", removed_host->name, src->name); - if (removed_host->self) { + if (removed_host->self && !src->self) { /* others will just disconnect us */ return; } - /* mark the host as removed and fully remove it later. this delay is - needed, because the removal may trigger director reconnections, - which may send the director back and we don't want to re-add it */ - removed_host->removed = TRUE; - if (dir->to_remove_dirs == NULL) { - dir->to_remove_dirs = - timeout_add(DIRECTOR_DELAYED_DIR_REMOVE_MSECS, - director_delayed_dir_remove_timeout, dir); + if (!removed_host->self) { + /* mark the host as removed and fully remove it later. this + delay is needed, because the removal may trigger director + reconnections, which may send the director back and we don't + want to re-add it */ + removed_host->removed = TRUE; + if (dir->to_remove_dirs == NULL) { + dir->to_remove_dirs = + timeout_add(DIRECTOR_DELAYED_DIR_REMOVE_MSECS, + director_delayed_dir_remove_timeout, dir); + } } /* if our left or ride side gets removed, notify them first @@ -554,7 +557,8 @@ void director_ring_remove(struct director_host *removed_host, conns = array_get(&dir->connections, &count); for (i = 0; i < count; ) { conn = conns[i]; - if (director_connection_get_host(conn) != removed_host) + if (director_connection_get_host(conn) != removed_host || + removed_host->self) i++; else { director_connection_deinit(&conn, "Removing from ring");