timesyncd: don't busy loop when we cannot connect to any servers
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include "log.h"
|
||||
#include "socket-util.h"
|
||||
#include "list.h"
|
||||
#include "ratelimit.h"
|
||||
#include "sd-event.h"
|
||||
#include "sd-resolve.h"
|
||||
#include "sd-daemon.h"
|
||||
@@ -83,6 +84,10 @@
|
||||
*/
|
||||
#define OFFSET_1900_1970 2208988800UL
|
||||
|
||||
#define RETRY_USEC (30*USEC_PER_SEC)
|
||||
#define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
|
||||
#define RATELIMIT_BURST 5
|
||||
|
||||
struct ntp_ts {
|
||||
be32_t sec;
|
||||
be32_t frac;
|
||||
@@ -129,6 +134,8 @@ struct Manager {
|
||||
|
||||
LIST_HEAD(ServerName, servers);
|
||||
|
||||
RateLimit ratelimit;
|
||||
|
||||
/* peer */
|
||||
sd_resolve_query *resolve_query;
|
||||
sd_event_source *event_receive;
|
||||
@@ -164,6 +171,9 @@ struct Manager {
|
||||
sd_event_source *event_clock_watch;
|
||||
int clock_watch_fd;
|
||||
|
||||
/* Retry connections */
|
||||
sd_event_source *event_retry;
|
||||
|
||||
/* Handle SIGINT/SIGTERM */
|
||||
sd_event_source *sigterm, *sigint;
|
||||
};
|
||||
@@ -847,6 +857,14 @@ static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct ad
|
||||
return manager_begin(m);
|
||||
}
|
||||
|
||||
static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
|
||||
assert(m);
|
||||
|
||||
return manager_connect(m);
|
||||
}
|
||||
|
||||
static int manager_connect(Manager *m) {
|
||||
|
||||
struct addrinfo hints = {
|
||||
@@ -859,6 +877,19 @@ static int manager_connect(Manager *m) {
|
||||
|
||||
manager_disconnect(m);
|
||||
|
||||
m->event_retry = sd_event_source_unref(m->event_retry);
|
||||
if (!ratelimit_test(&m->ratelimit)) {
|
||||
log_debug("Slowing down attempts to contact servers.");
|
||||
|
||||
r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
|
||||
if (r < 0) {
|
||||
log_error("Failed to create retry timer: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we already are operating on some address, switch to the
|
||||
* next one. */
|
||||
if (m->current_server_address && m->current_server_address->addresses_next)
|
||||
@@ -939,6 +970,8 @@ static int manager_new(Manager **ret) {
|
||||
|
||||
m->server_socket = m->clock_watch_fd = -1;
|
||||
|
||||
RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
|
||||
|
||||
r = sd_event_default(&m->event);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -974,6 +1007,8 @@ static void manager_free(Manager *m) {
|
||||
sd_event_source_unref(m->sigint);
|
||||
sd_event_source_unref(m->sigterm);
|
||||
|
||||
sd_event_source_unref(m->event_retry);
|
||||
|
||||
sd_resolve_unref(m->resolve);
|
||||
sd_event_unref(m->event);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user