changeset 22572:4a0792a03f5a

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)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 05 Oct 2017 11:51:23 +0300
parents 4057b92ed502
children 0813fee4d105
files src/director/director.c
diffstat 1 files changed, 14 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/director/director.c	Thu Oct 05 11:49:31 2017 +0300
+++ b/src/director/director.c	Thu Oct 05 11:51:23 2017 +0300
@@ -535,19 +535,22 @@
 	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
@@ -562,7 +565,8 @@
 	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");