]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
director: Added timeout to syncing to make sure we don't hang if it somehow gets...
authorTimo Sirainen <tss@iki.fi>
Tue, 17 Jan 2012 20:54:11 +0000 (22:54 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 17 Jan 2012 20:54:11 +0000 (22:54 +0200)
src/director/director-connection.c
src/director/director.c
src/director/director.h

index 7c6327d452c3dc66a142e48ffc8c21005f981263..0f7317878f965e33ef9d7fd70a868b05fd47ba52 100644 (file)
@@ -731,14 +731,8 @@ static bool director_connection_sync(struct director_connection *conn,
        if (host != NULL)
                director_connection_sync_host(conn, host, seq, line);
 
-       if (!dir->ring_synced && dir->left != NULL && dir->right != NULL &&
-           (host == NULL || !host->self)) {
-               /* send a new SYNC in case the previous one got dropped */
-               director_connection_send(dir->right,
-                       t_strdup_printf("SYNC\t%s\t%u\t%u\n",
-                                       net_ip2addr(&dir->self_ip),
-                                       dir->self_port, dir->sync_seq));
-       }
+       if (host == NULL || !host->self)
+               director_resend_sync(dir);
        return TRUE;
 }
 
index 7babb73cf65e759945db2231a6efa7678e4094f9..731bf81f29e862143ad6ab2a3ad840796fcb8a32 100644 (file)
@@ -17,6 +17,7 @@
 #define DIRECTOR_RECONNECT_TIMEOUT_MSECS (30*1000)
 #define DIRECTOR_USER_MOVE_TIMEOUT_MSECS (30*1000)
 #define DIRECTOR_USER_MOVE_FINISH_DELAY_MSECS (2*1000)
+#define DIRECTOR_SYNC_TIMEOUT_MSECS (15*1000)
 
 static bool director_is_self_ip_set(struct director *dir)
 {
@@ -224,17 +225,49 @@ void director_set_ring_synced(struct director *dir)
                        timeout_remove(&dir->to_reconnect);
        }
 
+       if (dir->to_sync != NULL)
+               timeout_remove(&dir->to_sync);
        dir->ring_synced = TRUE;
        dir->ring_last_sync_time = ioloop_time;
        director_set_state_changed(dir);
 }
 
+bool director_resend_sync(struct director *dir)
+{
+       if (!dir->ring_synced && dir->left != NULL && dir->right != NULL) {
+               /* send a new SYNC in case the previous one got dropped */
+               director_connection_send(dir->right,
+                       t_strdup_printf("SYNC\t%s\t%u\t%u\n",
+                                       net_ip2addr(&dir->self_ip),
+                                       dir->self_port, dir->sync_seq));
+               if (dir->to_sync != NULL)
+                       timeout_reset(dir->to_sync);
+               return TRUE;
+       }
+       return FALSE;
+}
+
+static void director_sync_timeout(struct director *dir)
+{
+       i_assert(!dir->ring_synced);
+
+       if (director_resend_sync(dir))
+               i_error("Ring SYNC appears to have got lost, resending");
+}
+
 void director_set_ring_unsynced(struct director *dir)
 {
        if (dir->ring_synced) {
                dir->ring_synced = FALSE;
                dir->ring_last_sync_time = ioloop_time;
        }
+
+       if (dir->to_sync == NULL) {
+               dir->to_sync = timeout_add(DIRECTOR_SYNC_TIMEOUT_MSECS,
+                                          director_sync_timeout, dir);
+       } else {
+               timeout_reset(dir->to_sync);
+       }
 }
 
 static void director_sync(struct director *dir)
@@ -618,6 +651,8 @@ void director_deinit(struct director **_dir)
                timeout_remove(&dir->to_handshake_warning);
        if (dir->to_request != NULL)
                timeout_remove(&dir->to_request);
+       if (dir->to_sync != NULL)
+               timeout_remove(&dir->to_sync);
        array_foreach(&dir->dir_hosts, hostp)
                director_host_free(*hostp);
        array_free(&dir->pending_requests);
index c6a712e78bb7f40455c56f5b929bd36e50b0e932..7695be232bf69d7ee6f265b6f14e06371461cf18 100644 (file)
@@ -24,6 +24,7 @@ struct director {
        /* all director connections */
        struct director_connection *connections;
        struct timeout *to_reconnect;
+       struct timeout *to_sync;
 
        /* current mail hosts */
        struct mail_host_list *mail_hosts;
@@ -75,6 +76,7 @@ void director_set_ring_handshaked(struct director *dir);
 void director_set_ring_synced(struct director *dir);
 void director_set_ring_unsynced(struct director *dir);
 void director_set_state_changed(struct director *dir);
+bool director_resend_sync(struct director *dir);
 
 void director_update_host(struct director *dir, struct director_host *src,
                          struct director_host *orig_src,