forked from pool/chrony
420 lines
11 KiB
Diff
420 lines
11 KiB
Diff
From 017d6f8f5630071e2a532f58f9513757d94ac7d5 Mon Sep 17 00:00:00 2001
|
|
From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
|
|
Date: Thu, 8 Feb 2024 14:36:25 +1100
|
|
Subject: [PATCH] reference: move leap second source into leapdb
|
|
|
|
Separate out source of leap second data into a new module in preparation
|
|
for supporting more sources such as leap-seconds.list.
|
|
---
|
|
Makefile.in | 2 +-
|
|
leapdb.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
leapdb.h | 37 +++++++++++++
|
|
main.c | 3 ++
|
|
reference.c | 99 +++--------------------------------
|
|
5 files changed, 194 insertions(+), 94 deletions(-)
|
|
create mode 100644 leapdb.c
|
|
create mode 100644 leapdb.h
|
|
|
|
diff --git a/Makefile.in b/Makefile.in
|
|
index 101e0c69..318109bb 100644
|
|
--- a/Makefile.in
|
|
+++ b/Makefile.in
|
|
@@ -37,7 +37,7 @@ GETDATE_CFLAGS = @GETDATE_CFLAGS@
|
|
|
|
EXTRA_OBJS = @EXTRA_OBJS@
|
|
|
|
-OBJS = array.o cmdparse.o conf.o local.o logging.o main.o memory.o quantiles.o \
|
|
+OBJS = array.o cmdparse.o conf.o leapdb.o local.o logging.o main.o memory.o quantiles.o \
|
|
reference.o regress.o rtc.o samplefilt.o sched.o socket.o sources.o sourcestats.o \
|
|
stubs.o smooth.o sys.o sys_null.o tempcomp.o util.o $(EXTRA_OBJS)
|
|
|
|
diff --git a/leapdb.c b/leapdb.c
|
|
new file mode 100644
|
|
index 00000000..676a0d5d
|
|
--- /dev/null
|
|
+++ b/leapdb.c
|
|
@@ -0,0 +1,147 @@
|
|
+/*
|
|
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
+
|
|
+ **********************************************************************
|
|
+ * Copyright (C) Miroslav Lichvar 2009-2018, 2020, 2022
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of version 2 of the GNU General Public License as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License along
|
|
+ * with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
+ *
|
|
+ **********************************************************************
|
|
+
|
|
+ =======================================================================
|
|
+
|
|
+ This module provides leap second information. */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include "sysincl.h"
|
|
+
|
|
+#include "conf.h"
|
|
+#include "leapdb.h"
|
|
+#include "logging.h"
|
|
+
|
|
+/* ================================================== */
|
|
+
|
|
+/* Name of a system timezone containing leap seconds occuring at midnight */
|
|
+static char *leap_tzname;
|
|
+
|
|
+/* ================================================== */
|
|
+
|
|
+static NTP_Leap
|
|
+get_tz_leap(time_t when, int *tai_offset)
|
|
+{
|
|
+ static time_t last_tz_leap_check;
|
|
+ static NTP_Leap tz_leap;
|
|
+ static int tz_tai_offset;
|
|
+
|
|
+ struct tm stm, *tm;
|
|
+ time_t t;
|
|
+ char *tz_env, tz_orig[128];
|
|
+
|
|
+ *tai_offset = tz_tai_offset;
|
|
+
|
|
+ /* Do this check at most twice a day */
|
|
+ when = when / (12 * 3600) * (12 * 3600);
|
|
+ if (last_tz_leap_check == when)
|
|
+ return tz_leap;
|
|
+
|
|
+ last_tz_leap_check = when;
|
|
+ tz_leap = LEAP_Normal;
|
|
+ tz_tai_offset = 0;
|
|
+
|
|
+ tm = gmtime(&when);
|
|
+ if (!tm)
|
|
+ return tz_leap;
|
|
+
|
|
+ stm = *tm;
|
|
+
|
|
+ /* Temporarily switch to the timezone containing leap seconds */
|
|
+ tz_env = getenv("TZ");
|
|
+ if (tz_env) {
|
|
+ if (strlen(tz_env) >= sizeof (tz_orig))
|
|
+ return tz_leap;
|
|
+ strcpy(tz_orig, tz_env);
|
|
+ }
|
|
+ setenv("TZ", leap_tzname, 1);
|
|
+ tzset();
|
|
+
|
|
+ /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */
|
|
+ t = mktime(&stm);
|
|
+ if (t != -1)
|
|
+ tz_tai_offset = t - when + 10;
|
|
+
|
|
+ /* Set the time to 23:59:60 and see how it overflows in mktime() */
|
|
+ stm.tm_sec = 60;
|
|
+ stm.tm_min = 59;
|
|
+ stm.tm_hour = 23;
|
|
+
|
|
+ t = mktime(&stm);
|
|
+
|
|
+ if (tz_env)
|
|
+ setenv("TZ", tz_orig, 1);
|
|
+ else
|
|
+ unsetenv("TZ");
|
|
+ tzset();
|
|
+
|
|
+ if (t == -1)
|
|
+ return tz_leap;
|
|
+
|
|
+ if (stm.tm_sec == 60)
|
|
+ tz_leap = LEAP_InsertSecond;
|
|
+ else if (stm.tm_sec == 1)
|
|
+ tz_leap = LEAP_DeleteSecond;
|
|
+
|
|
+ *tai_offset = tz_tai_offset;
|
|
+
|
|
+ return tz_leap;
|
|
+}
|
|
+
|
|
+/* ================================================== */
|
|
+
|
|
+void
|
|
+LDB_Initialise(void)
|
|
+{
|
|
+ int tai_offset;
|
|
+
|
|
+ leap_tzname = CNF_GetLeapSecTimezone();
|
|
+ if (leap_tzname) {
|
|
+ /* Check that the timezone has good data for Jun 30 2012 and Dec 31 2012 */
|
|
+ if (get_tz_leap(1341014400, &tai_offset) == LEAP_InsertSecond && tai_offset == 34 &&
|
|
+ get_tz_leap(1356912000, &tai_offset) == LEAP_Normal && tai_offset == 35) {
|
|
+ LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname);
|
|
+ } else {
|
|
+ LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname);
|
|
+ leap_tzname = NULL;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ================================================== */
|
|
+
|
|
+NTP_Leap
|
|
+LDB_GetLeap(time_t when, int *tai_offset)
|
|
+{
|
|
+ *tai_offset = 0;
|
|
+ if (leap_tzname)
|
|
+ return get_tz_leap(when, tai_offset);
|
|
+ return LEAP_Normal;
|
|
+}
|
|
+
|
|
+/* ================================================== */
|
|
+
|
|
+void
|
|
+LDB_Finalise(void)
|
|
+{
|
|
+ /* Nothing to do */
|
|
+}
|
|
diff --git a/leapdb.h b/leapdb.h
|
|
new file mode 100644
|
|
index 00000000..eab24141
|
|
--- /dev/null
|
|
+++ b/leapdb.h
|
|
@@ -0,0 +1,37 @@
|
|
+/*
|
|
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
+
|
|
+ **********************************************************************
|
|
+ * Copyright (C) Patrick Oppenlander 2023
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of version 2 of the GNU General Public License as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License along
|
|
+ * with this program; if not, write to the Free Software Foundation, Inc.,
|
|
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
+ *
|
|
+ **********************************************************************
|
|
+
|
|
+ =======================================================================
|
|
+
|
|
+ This module provides leap second information.
|
|
+
|
|
+ */
|
|
+
|
|
+#ifndef GOT_LEAPDB_H
|
|
+#define GOT_LEAPDB_H
|
|
+
|
|
+#include "ntp.h"
|
|
+
|
|
+extern void LDB_Initialise(void);
|
|
+extern NTP_Leap LDB_GetLeap(time_t when, int *tai_offset);
|
|
+extern void LDB_Finalise(void);
|
|
+
|
|
+#endif /* GOT_LEAPDB_H */
|
|
diff --git a/main.c b/main.c
|
|
index 21d0fe7f..cb240640 100644
|
|
--- a/main.c
|
|
+++ b/main.c
|
|
@@ -32,6 +32,7 @@
|
|
|
|
#include "main.h"
|
|
#include "sched.h"
|
|
+#include "leapdb.h"
|
|
#include "local.h"
|
|
#include "sys.h"
|
|
#include "ntp_io.h"
|
|
@@ -134,6 +135,7 @@ MAI_CleanupAndExit(void)
|
|
RCL_Finalise();
|
|
SRC_Finalise();
|
|
REF_Finalise();
|
|
+ LDB_Finalise();
|
|
RTC_Finalise();
|
|
SYS_Finalise();
|
|
|
|
@@ -655,6 +657,7 @@ int main
|
|
if (!geteuid())
|
|
LOG(LOGS_WARN, "Running with root privileges");
|
|
|
|
+ LDB_Initialise();
|
|
REF_Initialise();
|
|
SST_Initialise();
|
|
NSR_Initialise();
|
|
diff --git a/reference.c b/reference.c
|
|
index 97dfbe98..1ac6cb93 100644
|
|
--- a/reference.c
|
|
+++ b/reference.c
|
|
@@ -33,6 +33,7 @@
|
|
#include "reference.h"
|
|
#include "util.h"
|
|
#include "conf.h"
|
|
+#include "leapdb.h"
|
|
#include "logging.h"
|
|
#include "local.h"
|
|
#include "sched.h"
|
|
@@ -122,9 +123,6 @@ static int leap_in_progress;
|
|
/* Timer for the leap second handler */
|
|
static SCH_TimeoutID leap_timeout_id;
|
|
|
|
-/* Name of a system timezone containing leap seconds occuring at midnight */
|
|
-static char *leap_tzname;
|
|
-
|
|
/* ================================================== */
|
|
|
|
static LOG_FileID logfileid;
|
|
@@ -155,7 +153,6 @@ static int ref_adjustments;
|
|
|
|
/* ================================================== */
|
|
|
|
-static NTP_Leap get_tz_leap(time_t when, int *tai_offset);
|
|
static void update_leap_status(NTP_Leap leap, time_t now, int reset);
|
|
|
|
/* ================================================== */
|
|
@@ -195,7 +192,6 @@ REF_Initialise(void)
|
|
FILE *in;
|
|
double file_freq_ppm, file_skew_ppm;
|
|
double our_frequency_ppm;
|
|
- int tai_offset;
|
|
|
|
mode = REF_ModeNormal;
|
|
are_we_synchronised = 0;
|
|
@@ -260,18 +256,6 @@ REF_Initialise(void)
|
|
if (leap_mode == REF_LeapModeSystem && !LCL_CanSystemLeap())
|
|
leap_mode = REF_LeapModeStep;
|
|
|
|
- leap_tzname = CNF_GetLeapSecTimezone();
|
|
- if (leap_tzname) {
|
|
- /* Check that the timezone has good data for Jun 30 2012 and Dec 31 2012 */
|
|
- if (get_tz_leap(1341014400, &tai_offset) == LEAP_InsertSecond && tai_offset == 34 &&
|
|
- get_tz_leap(1356912000, &tai_offset) == LEAP_Normal && tai_offset == 35) {
|
|
- LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname);
|
|
- } else {
|
|
- LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname);
|
|
- leap_tzname = NULL;
|
|
- }
|
|
- }
|
|
-
|
|
CNF_GetMakeStep(&make_step_limit, &make_step_threshold);
|
|
CNF_GetMaxChange(&max_offset_delay, &max_offset_ignore, &max_offset);
|
|
CNF_GetMailOnChange(&do_mail_change, &mail_change_threshold, &mail_change_user);
|
|
@@ -593,77 +577,6 @@ is_leap_second_day(time_t when)
|
|
|
|
/* ================================================== */
|
|
|
|
-static NTP_Leap
|
|
-get_tz_leap(time_t when, int *tai_offset)
|
|
-{
|
|
- static time_t last_tz_leap_check;
|
|
- static NTP_Leap tz_leap;
|
|
- static int tz_tai_offset;
|
|
-
|
|
- struct tm stm, *tm;
|
|
- time_t t;
|
|
- char *tz_env, tz_orig[128];
|
|
-
|
|
- *tai_offset = tz_tai_offset;
|
|
-
|
|
- /* Do this check at most twice a day */
|
|
- when = when / (12 * 3600) * (12 * 3600);
|
|
- if (last_tz_leap_check == when)
|
|
- return tz_leap;
|
|
-
|
|
- last_tz_leap_check = when;
|
|
- tz_leap = LEAP_Normal;
|
|
- tz_tai_offset = 0;
|
|
-
|
|
- tm = gmtime(&when);
|
|
- if (!tm)
|
|
- return tz_leap;
|
|
-
|
|
- stm = *tm;
|
|
-
|
|
- /* Temporarily switch to the timezone containing leap seconds */
|
|
- tz_env = getenv("TZ");
|
|
- if (tz_env) {
|
|
- if (strlen(tz_env) >= sizeof (tz_orig))
|
|
- return tz_leap;
|
|
- strcpy(tz_orig, tz_env);
|
|
- }
|
|
- setenv("TZ", leap_tzname, 1);
|
|
- tzset();
|
|
-
|
|
- /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */
|
|
- t = mktime(&stm);
|
|
- if (t != -1)
|
|
- tz_tai_offset = t - when + 10;
|
|
-
|
|
- /* Set the time to 23:59:60 and see how it overflows in mktime() */
|
|
- stm.tm_sec = 60;
|
|
- stm.tm_min = 59;
|
|
- stm.tm_hour = 23;
|
|
-
|
|
- t = mktime(&stm);
|
|
-
|
|
- if (tz_env)
|
|
- setenv("TZ", tz_orig, 1);
|
|
- else
|
|
- unsetenv("TZ");
|
|
- tzset();
|
|
-
|
|
- if (t == -1)
|
|
- return tz_leap;
|
|
-
|
|
- if (stm.tm_sec == 60)
|
|
- tz_leap = LEAP_InsertSecond;
|
|
- else if (stm.tm_sec == 1)
|
|
- tz_leap = LEAP_DeleteSecond;
|
|
-
|
|
- *tai_offset = tz_tai_offset;
|
|
-
|
|
- return tz_leap;
|
|
-}
|
|
-
|
|
-/* ================================================== */
|
|
-
|
|
static void
|
|
leap_end_timeout(void *arg)
|
|
{
|
|
@@ -751,16 +664,16 @@ set_leap_timeout(time_t now)
|
|
static void
|
|
update_leap_status(NTP_Leap leap, time_t now, int reset)
|
|
{
|
|
- NTP_Leap tz_leap;
|
|
+ NTP_Leap ldb_leap;
|
|
int leap_sec, tai_offset;
|
|
|
|
leap_sec = 0;
|
|
tai_offset = 0;
|
|
|
|
- if (leap_tzname && now) {
|
|
- tz_leap = get_tz_leap(now, &tai_offset);
|
|
+ if (now) {
|
|
+ ldb_leap = LDB_GetLeap(now, &tai_offset);
|
|
if (leap == LEAP_Normal)
|
|
- leap = tz_leap;
|
|
+ leap = ldb_leap;
|
|
}
|
|
|
|
if (leap == LEAP_InsertSecond || leap == LEAP_DeleteSecond) {
|
|
@@ -1398,7 +1311,7 @@ REF_GetTaiOffset(struct timespec *ts)
|
|
{
|
|
int tai_offset;
|
|
|
|
- get_tz_leap(ts->tv_sec, &tai_offset);
|
|
+ LDB_GetLeap(ts->tv_sec, &tai_offset);
|
|
|
|
return tai_offset;
|
|
}
|