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.
This commit is contained in:
parent
eb26d13140
commit
017d6f8f56
5 changed files with 194 additions and 94 deletions
|
@ -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)
|
||||
|
||||
|
|
147
leapdb.c
Normal file
147
leapdb.c
Normal file
|
@ -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 */
|
||||
}
|
37
leapdb.h
Normal file
37
leapdb.h
Normal file
|
@ -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 */
|
3
main.c
3
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();
|
||||
|
|
99
reference.c
99
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue