]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Allow doveadm director ring remove for the same director
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 5 Oct 2017 08:51:23 +0000 (11:51 +0300)
committerAki Tuomi <aki.tuomi@dovecot.fi>
Thu, 5 Oct 2017 09:22:28 +0000 (12:22 +0300)
Fixes:
Panic: file doveadm-connection.c: line 859 (doveadm_connection_cmd_run): assertion failed: (conn->dir->right == NULL && conn->dir->left == NULL)

src/director/director.c

index 423e941ed94d5236e2b3e7961f938491dc93d7bc..650fa05d9d5fba065bd94e830651ce784430bc68 100644 (file)
@@ -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");