Blob Blame History Raw
From 6aa136216f2f78a840215e53ababeea7b65fc061 Mon Sep 17 00:00:00 2001
From: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed, 27 Aug 2014 16:47:24 +0200
Subject: [PATCH 07/12] timesyncd: wait before reconnecting to first server

When all servers are exhausted, wait for one poll interval before trying
to connect again to the first server in the list. Also, keep increasing
the polling interval to make sure a client not getting any valid replies
will not send requests to any server more frequently than is allowed by
the maximum polling interval.

(cherry picked from commit 63463bf091949e0178b749016828ec400c106582)
---
 src/timesync/timesyncd-manager.c | 24 +++++++++++++++++++++++-
 src/timesync/timesyncd-manager.h |  1 +
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 696dd10..b7b39ef 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -875,6 +875,7 @@ int manager_connect(Manager *m) {
                         manager_set_server_name(m, m->current_server_name->names_next);
                 else {
                         ServerName *f;
+                        bool restart = true;
 
                         /* Our current server name list is exhausted,
                          * let's find the next one to iterate. First
@@ -891,6 +892,8 @@ int manager_connect(Manager *m) {
                                 f = m->link_servers;
                                 if (!f)
                                         f = m->system_servers;
+                                else
+                                        restart = false;
                         }
 
                         if (!f)
@@ -902,6 +905,25 @@ int manager_connect(Manager *m) {
                                 return 0;
                         }
 
+                        if (restart && !m->exhausted_servers && m->poll_interval_usec) {
+                                log_debug("Waiting after exhausting servers.");
+                                r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + m->poll_interval_usec, 0, manager_retry_connect, m);
+                                if (r < 0) {
+                                        log_error("Failed to create retry timer: %s", strerror(-r));
+                                        return r;
+                                }
+
+                                m->exhausted_servers = true;
+
+                                /* Increase the polling interval */
+                                if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                                        m->poll_interval_usec *= 2;
+
+                                return 0;
+                        }
+
+                        m->exhausted_servers = false;
+
                         manager_set_server_name(m, f);
                 }
 
@@ -1042,7 +1064,7 @@ static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t re
         online = network_is_online();
 
         /* check if the client is currently connected */
-        connected = m->server_socket >= 0 || m->resolve_query;
+        connected = m->server_socket >= 0 || m->resolve_query || m->exhausted_servers;
 
         if (connected && !online) {
                 log_info("No network connectivity, watching for changes.");
diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
index 2345bf8..bb3e509 100644
--- a/src/timesync/timesyncd-manager.h
+++ b/src/timesync/timesyncd-manager.h
@@ -41,6 +41,7 @@ struct Manager {
         LIST_HEAD(ServerName, fallback_servers);
 
         RateLimit ratelimit;
+        bool exhausted_servers;
 
         /* network */
         sd_event_source *network_event_source;
-- 
2.1.0