From f5d1b8fb740636cb106675de1f89c361d12869e7 Mon Sep 17 00:00:00 2001 From: Chris Perl Date: Tue, 10 Oct 2017 13:23:21 -0400 Subject: [PATCH] refclock: add tai option This option is for indicating to chronyd that the reference clock is kept in TAI and that chrony should attempt to convert from TAI to UTC by using the timezone configured by the "leapsectz" directive. --- conf.c | 7 ++++++- doc/chrony.conf.adoc | 7 +++++++ refclock.c | 16 ++++++++++++++++ refclock.h | 1 + 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/conf.c b/conf.c index 363e8b8..3859d74 100644 --- a/conf.c +++ b/conf.c @@ -681,7 +681,7 @@ static void parse_refclock(char *line) { int n, poll, dpoll, filter_length, pps_rate, min_samples, max_samples, sel_options; - int max_lock_age, pps_forced, stratum; + int max_lock_age, pps_forced, stratum, tai; uint32_t ref_id, lock_ref_id; double offset, delay, precision, max_dispersion, pulse_width; char *p, *cmd, *name, *param; @@ -705,6 +705,7 @@ parse_refclock(char *line) max_lock_age = 2; lock_ref_id = 0; stratum = 0; + tai = 0; if (!*line) { command_parse_error(); @@ -779,6 +780,9 @@ parse_refclock(char *line) if (sscanf(line, "%d%n", &stratum, &n) != 1 || stratum >= NTP_MAX_STRATUM || stratum < 0) break; + } else if (!strcasecmp(cmd, "tai")) { + n = 0; + tai = 1; } else if (!strcasecmp(cmd, "width")) { if (sscanf(line, "%lf%n", &pulse_width, &n) != 1) break; @@ -817,6 +821,7 @@ parse_refclock(char *line) refclock->max_samples = max_samples; refclock->sel_options = sel_options; refclock->stratum = stratum; + refclock->tai = tai; refclock->offset = offset; refclock->delay = delay; refclock->precision = precision; diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index 82c56c1..b4bb235 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -549,6 +549,13 @@ but not very precise, reference clock to be safely combined with unauthenticated NTP sources in order to improve the accuracy of the clock. They can be selected and used for synchronisation only if they agree with the trusted and required source. +*tai*::: +This option indicates that the time on the given reference clock is kept in TAI +instead of UTC and that *chronyd* should apply the current TAI-UTC offset to +samples taken from this refclock. To use this, the *leapsectz* directive must +be used as *chronyd* uses the timezone files to compute the TAI-UTC offset. +This option does not make sense if the given refclock is only being used for +PPS input. *minsamples* _samples_::: Set the minimum number of samples kept for this source. This overrides the <> directive. diff --git a/refclock.c b/refclock.c index bcb3064..c522731 100644 --- a/refclock.c +++ b/refclock.c @@ -80,6 +80,7 @@ struct RCL_Instance_Record { int pps_active; int max_lock_age; int stratum; + int tai; struct MedianFilter filter; uint32_t ref_id; uint32_t lock_ref; @@ -190,6 +191,9 @@ RCL_AddRefclock(RefclockParameters *params) return 0; } + if (params->tai && !CNF_GetLeapSecTimezone()) + LOG_FATAL("refclock tai option requires leapsectz"); + inst->data = NULL; inst->driver_parameter = params->driver_parameter; inst->driver_parameter_length = 0; @@ -202,6 +206,7 @@ RCL_AddRefclock(RefclockParameters *params) inst->pps_active = 0; inst->max_lock_age = params->max_lock_age; inst->stratum = params->stratum; + inst->tai = params->tai; inst->lock_ref = params->lock_ref_id; inst->offset = params->offset; inst->delay = params->delay; @@ -387,6 +392,17 @@ RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset return 0; } + if (instance->tai) { + int tai_offset = REF_GetTaiOffset(sample_time); + + if (!tai_offset) { + DEBUG_LOG("refclock sample ignored unknown TAI offset"); + return 0; + } + + offset -= tai_offset; + } + filter_add_sample(&instance->filter, &cooked_time, offset - correction + instance->offset, dispersion); instance->pps_active = 0; diff --git a/refclock.h b/refclock.h index 7508f3d..724f620 100644 --- a/refclock.h +++ b/refclock.h @@ -44,6 +44,7 @@ typedef struct { int sel_options; int max_lock_age; int stratum; + int tai; uint32_t ref_id; uint32_t lock_ref_id; double offset;