diff --git a/.chrony.metadata b/.chrony.metadata index 59f2c95..7e646af 100644 --- a/.chrony.metadata +++ b/.chrony.metadata @@ -1,2 +1,2 @@ -4661e5df181a9761b73caeaef2f2ab755bbe086a SOURCES/chrony-4.5.tar.gz -e021461c23fe4e5c46fd53c449587d8f6cc217ae SOURCES/clknetsim-5d1dc0.tar.gz +35b070fdd446080232844ac9f70f84ca1823206f SOURCES/chrony-4.6.1.tar.gz +a3289d3e8688b0818e67d3b7338e8b73501bef1e SOURCES/clknetsim-40bb97.tar.gz diff --git a/.gitignore b/.gitignore index a1b6ce7..2bb0b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/chrony-4.5.tar.gz -SOURCES/clknetsim-5d1dc0.tar.gz +SOURCES/chrony-4.6.1.tar.gz +SOURCES/clknetsim-40bb97.tar.gz diff --git a/SOURCES/chrony-4.5-tar-gz-asc.txt b/SOURCES/chrony-4.5-tar-gz-asc.txt deleted file mode 100644 index 16dae25..0000000 --- a/SOURCES/chrony-4.5-tar-gz-asc.txt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEjzdcfo0O4SWj071RU34rdvdoDawFAmVvJPkACgkQU34rdvdo -DawQjw//Zkq4UTPZDpU/gifjUtE/jpIa6+tyhSFpRI5abNScOPaEa8nZz6Q33/s4 -qiS9RJh1AA13xnal7bIHsixadON01x91ysW1sbNhFx942SwTpk00wDdLmySqW+u5 -klrTfGlGRejp7ahasbXx/dXqk3Sz+J19YIvdz2X1o2HaUZwp1SIwq5Y8BYS8iE0a -G5ov/ail2965hwSoYWNbR7/UuOTEO3YgRk2YSpKKKGJgL27pAzwGlOVwgP9JLAD0 -WsGDEpn+EY+4BOkwMyFeACOHyJ+QCcpKXF9B6CGJELyPqTp2uQy+OkaF4VtkGvpp -wRs6IhMoHFt5NjvCiBhOMvocKd6JrxDxN84gGhSG6OtSFp8GZoFhTxIp//mnZDoz -WPl/Z+n3yABdaG7IWavl6tn2wvipMsgcTJHxRYg6A4d2+mKKy0pRyfLUtGTM9EA/ -NEhTIHVZZLORNK7zPaB8CkFmmsmDQVhowBjXjFcq2HDNzQawbU5gjWUBEH+4R4bq -rb4P9Eg3Kus0fvBxj4z72XkzYGNn951YFhwW26x4w09+J35/1eoshNkBaPfOdsRf -Xgb37MmEe5yfU32k27aYtERnH9w/+rOk1RISrVcK0c87uz0RnzPN5HBzc4PnEpx6 -KQFkFxVaaMeJNc0Ca5/u9aE9nli1DIS8Afo/Z4zQtjVMqLsvecQ= -=4/yB ------END PGP SIGNATURE----- diff --git a/SOURCES/chrony-4.6.1-tar-gz-asc.txt b/SOURCES/chrony-4.6.1-tar-gz-asc.txt new file mode 100644 index 0000000..e33cef1 --- /dev/null +++ b/SOURCES/chrony-4.6.1-tar-gz-asc.txt @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEjzdcfo0O4SWj071RU34rdvdoDawFAmcFKp4ACgkQU34rdvdo +DazMmxAAlSONiDmb/EpwVBigLlVdtyelr6G/9ISMQv/f3CzNlliZOWBQBYiK8UfL ++ohx4uh3R10kWMMJEpeJ7VQMkh3Jn6BKWE3QKQQDKI/Cd39ceeTO57ZZreI3dTRh +8w9xxdwYwEobHhabXQ7wCXDIvssyC6w5LXw4dLmo3N1dC7ZNxJhYgmXVScw6RK5m +bc5Ch/H9bxD1xZiWflXC2dW57nJumJDnMlRVdYot9P2zD0DrGy3cFmh6w89gip67 +T2PrhQ9vQUt8zWKEt9CQi0EtDJ8q1B7HKTLSmM6iEGRjphij+2Z8i0EiQRYA+V++ +ZQVGg+O6MJYuNbPGdwVBZZMVS4wF3mnNkmBk0/tlxNnNH9dqQ1RquRxQCUPDsGwF +dZUmptZWctNaM7TfICdnjEWz/7flR52+BMi5VRYvAK9MCqhTCkg5bw53r02wNSTK +M2PXMRbGuYUGsPDkXaKHf478uhiZF+3ka6tiomK0RT9ip304qhNxdzhsW942ryH2 +yUaFFRGpNk+KJI7e7GfmWmRrBhpi4tqsaFQ4dvUXhlSmk4zVbHIzkgj6Ej6pgJrW +w3lUOlQ49DfNkUnZIVAFHJ6LAmeejTvMNlq9IKHfuFA18X7yhHQI49SXiOUOhKD2 +/z6nMP0cjxQ6eij5UupKx/6/IHTIt9uUpTU1taxAsVXKcBemkN8= +=/5W0 +-----END PGP SIGNATURE----- diff --git a/SOURCES/chrony-defconfig.patch b/SOURCES/chrony-defconfig.patch new file mode 100644 index 0000000..92d5669 --- /dev/null +++ b/SOURCES/chrony-defconfig.patch @@ -0,0 +1,15 @@ +diff --git a/examples/chrony.conf.example2 b/examples/chrony.conf.example2 +index 03e7d47b..bf2bbdda 100644 +--- a/examples/chrony.conf.example2 ++++ b/examples/chrony.conf.example2 +@@ -37,8 +37,8 @@ ntsdumpdir /var/lib/chrony + # Insert/delete leap seconds by slewing instead of stepping. + #leapsecmode slew + +-# Set the TAI-UTC offset of the system clock. +-#leapseclist /usr/share/zoneinfo/leap-seconds.list ++# Get TAI-UTC offset and leap seconds from the system tz database. ++#leapsectz right/UTC + + # Specify directory for log files. + logdir /var/log/chrony diff --git a/SOURCES/chrony-leaplist-man.patch b/SOURCES/chrony-leaplist-man.patch deleted file mode 100644 index 4a1ee13..0000000 --- a/SOURCES/chrony-leaplist-man.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- chrony-4.5/doc/chrony.conf.man.in 2023-12-05 14:26:13.000000000 +0100 -+++ chrony.conf.man.in 2024-07-30 14:17:30.000000000 +0200 -@@ -908,9 +915,10 @@ - .RS 4 - This option indicates that the reference clock keeps time in TAI instead of UTC - and that \fBchronyd\fP should correct its offset by the current TAI\-UTC offset. The --\fBleapsectz\fP directive must be used with this option and the --database must be kept up to date in order for this correction to work as --expected. This option does not make sense with PPS refclocks. -+\fBleapsectz\fP or \fBleapseclist\fP directive must be -+used with this option and the database must be kept up to date in order for -+this correction to work as expected. This option does not make sense with PPS -+refclocks. - .RE - .sp - \fBlocal\fP -@@ -1652,6 +1660,25 @@ - .if n .RE - .RE - .sp -+\fBleapseclist\fP \fIfile\fP -+.RS 4 -+This directive specifies the path to a file containing a list of leap seconds -+and TAI\-UTC offsets in NIST/IERS format. It is recommended to use -+the file \fIleap\-seconds.list\fP usually included with the system timezone -+database. The behaviour of this directive is otherwise equivalent to -+\fBleapsectz\fP. -+.sp -+An example of this directive is: -+.sp -+.if n .RS 4 -+.nf -+.fam C -+leapseclist /usr/share/zoneinfo/leap\-seconds.list -+.fam -+.fi -+.if n .RE -+.RE -+.sp - \fBmakestep\fP \fIthreshold\fP \fIlimit\fP - .RS 4 - Normally \fBchronyd\fP will cause the system to gradually correct any time offset, diff --git a/SOURCES/chrony-leaplist.patch b/SOURCES/chrony-leaplist.patch deleted file mode 100644 index b048ee6..0000000 --- a/SOURCES/chrony-leaplist.patch +++ /dev/null @@ -1,1304 +0,0 @@ -commit 5035e5779503c2c38d09eb04f58480739828c6fa -Author: Patrick Oppenlander -Date: Thu Feb 8 14:36:25 2024 +1100 - - 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. - -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; - } - -commit 5f45313e7b960ad5aa094e529533b563968c3d07 -Author: Patrick Oppenlander -Date: Thu Feb 8 14:36:26 2024 +1100 - - leapdb: make twice per day check logic common - - We want to do the twice per day check regardless of the data source. - Move the check up one level from get_tz_leap() into LDB_GetLeap(). - -diff --git a/leapdb.c b/leapdb.c -index 676a0d5d..32f753aa 100644 ---- a/leapdb.c -+++ b/leapdb.c -@@ -41,24 +41,10 @@ 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; -+ NTP_Leap tz_leap = LEAP_Normal; - - tm = gmtime(&when); - if (!tm) -@@ -79,7 +65,7 @@ get_tz_leap(time_t when, int *tai_offset) - /* 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; -+ *tai_offset = t - when + 10; - - /* Set the time to 23:59:60 and see how it overflows in mktime() */ - stm.tm_sec = 60; -@@ -102,8 +88,6 @@ get_tz_leap(time_t when, int *tai_offset) - else if (stm.tm_sec == 1) - tz_leap = LEAP_DeleteSecond; - -- *tai_offset = tz_tai_offset; -- - return tz_leap; - } - -@@ -132,10 +116,25 @@ LDB_Initialise(void) - NTP_Leap - LDB_GetLeap(time_t when, int *tai_offset) - { -- *tai_offset = 0; -+ static time_t last_ldb_leap_check; -+ static NTP_Leap ldb_leap; -+ static int ldb_tai_offset; -+ -+ /* Do this check at most twice a day */ -+ when = when / (12 * 3600) * (12 * 3600); -+ if (last_ldb_leap_check == when) -+ goto out; -+ -+ last_ldb_leap_check = when; -+ ldb_leap = LEAP_Normal; -+ ldb_tai_offset = 0; -+ - if (leap_tzname) -- return get_tz_leap(when, tai_offset); -- return LEAP_Normal; -+ ldb_leap = get_tz_leap(when, &ldb_tai_offset); -+ -+out: -+ *tai_offset = ldb_tai_offset; -+ return ldb_leap; - } - - /* ================================================== */ - -commit c857cfbaa6c1d6a9e7dad454287a537f1e1dbab9 -Author: Patrick Oppenlander -Date: Thu Feb 8 14:36:27 2024 +1100 - - leapdb: move source check into separate function - - The sanity checks are valid for all possible sources of leap second - information, so move them into a separate function check_leap_source(). - -diff --git a/leapdb.c b/leapdb.c -index 32f753aa..aa49b3c4 100644 ---- a/leapdb.c -+++ b/leapdb.c -@@ -93,22 +93,32 @@ get_tz_leap(time_t when, int *tai_offset) - - /* ================================================== */ - -+static int -+check_leap_source(NTP_Leap (*src)(time_t when, int *tai_offset)) -+{ -+ int tai_offset = 0; -+ -+ /* Check that the leap second source has good data for Jun 30 2012 and Dec 31 2012 */ -+ if (src(1341014400, &tai_offset) == LEAP_InsertSecond && tai_offset == 34 && -+ src(1356912000, &tai_offset) == LEAP_Normal && tai_offset == 35) -+ return 1; -+ -+ return 0; -+} -+ -+/* ================================================== */ -+ - 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; -- } -+ if (leap_tzname && !check_leap_source(get_tz_leap)) { -+ LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname); -+ leap_tzname = NULL; - } -+ -+ if (leap_tzname) -+ LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname); - } - - /* ================================================== */ - -commit 8cee4481073854f98db2c8473f702b3df35a5e1c -Author: Patrick Oppenlander -Date: Thu Feb 8 14:36:28 2024 +1100 - - leapdb: support leap-seconds.list as second source - - The existing implementation of getting leap second information from a - timezone in get_tz_leap() relies on non-portable C library behaviour. - - Specifically, mktime is not required to return '60' in the tm_sec field - when a leap second is inserted leading to "Timezone right/UTC failed - leap second check, ignoring" errors on musl based systems. - - This patch adds support for getting leap second information from the - leap-seconds.list file included with tzdata and adds a new configuration - directive leapseclist to switch on the feature. - - (Removed chrony.conf.adoc patch to avoid triggering asciidoctor) - -diff --git a/conf.c b/conf.c -index 522e235a..cb872ba9 100644 ---- a/conf.c -+++ b/conf.c -@@ -249,6 +249,9 @@ static REF_LeapMode leapsec_mode = REF_LeapModeSystem; - /* Name of a system timezone containing leap seconds occuring at midnight */ - static char *leapsec_tz = NULL; - -+/* File name of leap seconds list, usually /usr/share/zoneinfo/leap-seconds.list */ -+static char *leapsec_list = NULL; -+ - /* Name of the user to which will be dropped root privileges. */ - static char *user; - -@@ -471,6 +474,7 @@ CNF_Finalise(void) - Free(hwclock_file); - Free(keys_file); - Free(leapsec_tz); -+ Free(leapsec_list); - Free(logdir); - Free(bind_ntp_iface); - Free(bind_acq_iface); -@@ -620,6 +624,8 @@ CNF_ParseLine(const char *filename, int number, char *line) - parse_leapsecmode(p); - } else if (!strcasecmp(command, "leapsectz")) { - parse_string(p, &leapsec_tz); -+ } else if (!strcasecmp(command, "leapseclist")) { -+ parse_string(p, &leapsec_list); - } else if (!strcasecmp(command, "local")) { - parse_local(p); - } else if (!strcasecmp(command, "lock_all")) { -@@ -2387,6 +2393,14 @@ CNF_GetLeapSecTimezone(void) - - /* ================================================== */ - -+char * -+CNF_GetLeapSecList(void) -+{ -+ return leapsec_list; -+} -+ -+/* ================================================== */ -+ - int - CNF_GetSchedPriority(void) - { -diff --git a/conf.h b/conf.h -index 58ebdeb0..4c0a7879 100644 ---- a/conf.h -+++ b/conf.h -@@ -91,6 +91,7 @@ extern char *CNF_GetNtpSigndSocket(void); - extern char *CNF_GetPidFile(void); - extern REF_LeapMode CNF_GetLeapSecMode(void); - extern char *CNF_GetLeapSecTimezone(void); -+extern char *CNF_GetLeapSecList(void); - - /* Value returned in ppm, as read from file */ - extern double CNF_GetMaxUpdateSkew(void); -diff --git a/leapdb.c b/leapdb.c -index aa49b3c4..e748e001 100644 ---- a/leapdb.c -+++ b/leapdb.c -@@ -3,6 +3,7 @@ - - ********************************************************************** - * Copyright (C) Miroslav Lichvar 2009-2018, 2020, 2022 -+ * Copyright (C) Patrick Oppenlander 2023, 2024 - * - * 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 -@@ -30,11 +31,20 @@ - #include "conf.h" - #include "leapdb.h" - #include "logging.h" -+#include "util.h" - - /* ================================================== */ - --/* Name of a system timezone containing leap seconds occuring at midnight */ --static char *leap_tzname; -+/* Source of leap second data */ -+enum { -+ SRC_NONE, -+ SRC_TIMEZONE, -+ SRC_LIST, -+} leap_src; -+ -+/* Offset between leap-seconds.list timestamp epoch and Unix epoch. -+ leap-seconds.list epoch is 1 Jan 1900, 00:00:00 */ -+#define LEAP_SEC_LIST_OFFSET 2208988800 - - /* ================================================== */ - -@@ -59,7 +69,7 @@ get_tz_leap(time_t when, int *tai_offset) - return tz_leap; - strcpy(tz_orig, tz_env); - } -- setenv("TZ", leap_tzname, 1); -+ setenv("TZ", CNF_GetLeapSecTimezone(), 1); - tzset(); - - /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */ -@@ -93,6 +103,91 @@ get_tz_leap(time_t when, int *tai_offset) - - /* ================================================== */ - -+static NTP_Leap -+get_list_leap(time_t when, int *tai_offset) -+{ -+ FILE *f; -+ char line[1024]; -+ NTP_Leap ret_leap = LEAP_Normal; -+ int ret_tai_offset = 0, prev_lsl_tai_offset = 10; -+ int64_t lsl_updated = 0, lsl_expiry = 0; -+ const char *leap_sec_list = CNF_GetLeapSecList(); -+ -+ if (!(f = UTI_OpenFile(NULL, leap_sec_list, NULL, 'r', 0))) { -+ LOG(LOGS_ERR, "Failed to open leap seconds list %s", leap_sec_list); -+ goto out; -+ } -+ -+ /* Leap second happens at midnight */ -+ when = (when / (24 * 3600) + 1) * (24 * 3600); -+ -+ /* leap-seconds.list timestamps are relative to 1 Jan 1900, 00:00:00 */ -+ when += LEAP_SEC_LIST_OFFSET; -+ -+ while (fgets(line, sizeof line, f) > 0) { -+ int64_t lsl_when; -+ int lsl_tai_offset; -+ char *p; -+ -+ /* Ignore blank lines */ -+ for (p = line; *p && isspace(*p); ++p) -+ ; -+ if (!*p) -+ continue; -+ -+ if (*line == '#') { -+ /* Update time line starts with #$ */ -+ if (line[1] == '$' && sscanf(line + 2, "%"SCNd64, &lsl_updated) != 1) -+ goto error; -+ /* Expiration time line starts with #@ */ -+ if (line[1] == '@' && sscanf(line + 2, "%"SCNd64, &lsl_expiry) != 1) -+ goto error; -+ /* Comment or a special comment we don't care about */ -+ continue; -+ } -+ -+ /* Leap entry */ -+ if (sscanf(line, "%"SCNd64" %d", &lsl_when, &lsl_tai_offset) != 2) -+ goto error; -+ -+ if (when == lsl_when) { -+ if (lsl_tai_offset > prev_lsl_tai_offset) -+ ret_leap = LEAP_InsertSecond; -+ else if (lsl_tai_offset < prev_lsl_tai_offset) -+ ret_leap = LEAP_DeleteSecond; -+ /* When is rounded to the end of the day, so offset hasn't changed yet! */ -+ ret_tai_offset = prev_lsl_tai_offset; -+ } else if (when > lsl_when) { -+ ret_tai_offset = lsl_tai_offset; -+ } -+ -+ prev_lsl_tai_offset = lsl_tai_offset; -+ } -+ -+ /* Make sure the file looks sensible */ -+ if (!feof(f) || !lsl_updated || !lsl_expiry) -+ goto error; -+ -+ if (when >= lsl_expiry) -+ LOG(LOGS_WARN, "Leap second list %s needs update", leap_sec_list); -+ -+ goto out; -+ -+error: -+ if (f) -+ fclose(f); -+ LOG(LOGS_ERR, "Failed to parse leap seconds list %s", leap_sec_list); -+ return LEAP_Normal; -+ -+out: -+ if (f) -+ fclose(f); -+ *tai_offset = ret_tai_offset; -+ return ret_leap; -+} -+ -+/* ================================================== */ -+ - static int - check_leap_source(NTP_Leap (*src)(time_t when, int *tai_offset)) - { -@@ -111,14 +206,27 @@ check_leap_source(NTP_Leap (*src)(time_t when, int *tai_offset)) - void - LDB_Initialise(void) - { -+ const char *leap_tzname, *leap_sec_list; -+ - leap_tzname = CNF_GetLeapSecTimezone(); - if (leap_tzname && !check_leap_source(get_tz_leap)) { - LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname); - leap_tzname = NULL; - } - -- if (leap_tzname) -+ leap_sec_list = CNF_GetLeapSecList(); -+ if (leap_sec_list && !check_leap_source(get_list_leap)) { -+ LOG(LOGS_WARN, "Leap second list %s failed check, ignoring", leap_sec_list); -+ leap_sec_list = NULL; -+ } -+ -+ if (leap_sec_list) { -+ LOG(LOGS_INFO, "Using leap second list %s", leap_sec_list); -+ leap_src = SRC_LIST; -+ } else if (leap_tzname) { - LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname); -+ leap_src = SRC_TIMEZONE; -+ } - } - - /* ================================================== */ -@@ -139,8 +247,16 @@ LDB_GetLeap(time_t when, int *tai_offset) - ldb_leap = LEAP_Normal; - ldb_tai_offset = 0; - -- if (leap_tzname) -+ switch (leap_src) { -+ case SRC_NONE: -+ break; -+ case SRC_TIMEZONE: - ldb_leap = get_tz_leap(when, &ldb_tai_offset); -+ break; -+ case SRC_LIST: -+ ldb_leap = get_list_leap(when, &ldb_tai_offset); -+ break; -+ } - - out: - *tai_offset = ldb_tai_offset; -diff --git a/refclock.c b/refclock.c -index 84f7439c..44ba6d5c 100644 ---- a/refclock.c -+++ b/refclock.c -@@ -166,8 +166,8 @@ RCL_AddRefclock(RefclockParameters *params) - if (!inst->driver->init && !inst->driver->poll) - LOG_FATAL("refclock driver %s is not compiled in", params->driver_name); - -- if (params->tai && !CNF_GetLeapSecTimezone()) -- LOG_FATAL("refclock tai option requires leapsectz"); -+ if (params->tai && !CNF_GetLeapSecList() && !CNF_GetLeapSecTimezone()) -+ LOG_FATAL("refclock tai option requires leapseclist or leapsectz"); - - inst->data = NULL; - inst->driver_parameter = Strdup(params->driver_parameter); - -commit bb98f492ef7ecec5d9a33c3b18ff46ee4964d01d -Author: Patrick Oppenlander -Date: Thu Feb 8 14:36:29 2024 +1100 - - test: add leapdb unit test - -diff --git a/test/unit/leapdb.c b/test/unit/leapdb.c -new file mode 100644 -index 00000000..509fc394 ---- /dev/null -+++ b/test/unit/leapdb.c -@@ -0,0 +1,104 @@ -+/* -+ ********************************************************************** -+ * 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. -+ * -+ ********************************************************************** -+ */ -+ -+#include -+#include "test.h" -+ -+struct test_vector { -+ time_t when; -+ int tai_offset; -+ NTP_Leap leap; -+ int fake; -+} tests[] = { -+ /* leapdb.list is a cut down version of leap-seconds.list */ -+ {3439756800, 34, LEAP_InsertSecond, 0}, /* 1 Jan 2009 */ -+ {3550089600, 35, LEAP_InsertSecond, 0}, /* 1 Jul 2012 */ -+ {3644697600, 36, LEAP_InsertSecond, 0}, /* 1 Jul 2015 */ -+ {3692217600, 37, LEAP_InsertSecond, 0}, /* 1 Jan 2017 */ -+ {3786825600, 36, LEAP_DeleteSecond, 1}, /* 1 Jan 2020 fake in leapdb.list */ -+}; -+ -+static void -+test_leap_source(NTP_Leap (*fn)(time_t when, int *tai_offset), -+ int skip_fakes) -+{ -+ int prev_tai_offset = 34; -+ for (int i = 0; i < sizeof tests / sizeof tests[0]; ++i) { -+ struct test_vector *t = tests + i; -+ -+ NTP_Leap leap; -+ int tai_offset = -1; -+ -+ /* Our unit test leapdb.list contains a fake entry removing a leap second. -+ * Skip this when testing with the right/UTC timezone using mktime(). */ -+ if (skip_fakes && t->fake) -+ continue; -+ -+ /* One second before leap second */ -+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET - 1, &tai_offset); -+ TEST_CHECK(leap == t->leap); -+ TEST_CHECK(tai_offset = prev_tai_offset); -+ -+ /* Exactly on leap second */ -+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET, &tai_offset); -+ TEST_CHECK(leap == LEAP_Normal); -+ TEST_CHECK(tai_offset == t->tai_offset); -+ -+ /* One second after leap second */ -+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET + 1, &tai_offset); -+ TEST_CHECK(leap == LEAP_Normal); -+ TEST_CHECK(tai_offset == t->tai_offset); -+ -+ prev_tai_offset = t->tai_offset; -+ } -+} -+ -+void -+test_unit(void) -+{ -+ char conf[][100] = { -+ "leapsectz right/UTC", -+ "leapseclist leapdb.list" -+ }; -+ -+ CNF_Initialise(0, 0); -+ for (int i = 0; i < sizeof conf / sizeof conf[0]; i++) -+ CNF_ParseLine(NULL, i + 1, conf[i]); -+ LDB_Initialise(); -+ -+ if (check_leap_source(get_tz_leap)) { -+ DEBUG_LOG("testing get_tz_leap"); -+ test_leap_source(get_tz_leap, 1); -+ } else { -+ DEBUG_LOG("Skipping get_tz_leap test. Either the right/UTC timezone is " -+ "missing, or mktime() doesn't support leap seconds."); -+ } -+ -+ DEBUG_LOG("testing get_list_leap"); -+ TEST_CHECK(check_leap_source(get_list_leap)); -+ test_leap_source(get_list_leap, 0); -+ -+ /* This exercises the twice-per-day logic */ -+ DEBUG_LOG("testing LDB_GetLeap"); -+ test_leap_source(LDB_GetLeap, 1); -+ -+ LDB_Finalise(); -+ CNF_Finalise(); -+} -diff --git a/test/unit/leapdb.list b/test/unit/leapdb.list -new file mode 100644 -index 00000000..5dc2188f ---- /dev/null -+++ b/test/unit/leapdb.list -@@ -0,0 +1,22 @@ -+# -+# Cut down version of leap-seconds.list for unit test. -+# -+# Blank lines need to be ignored, so include a few for testing. -+# Whitespace errors on non-blank lines below are copied from the original file. -+# -+ -+# Leap second data update time -+#$ 3676924800 -+# -+# File update time -+#@ 3928521600 -+ -+3439756800 34 # 1 Jan 2009 -+3550089600 35 # 1 Jul 2012 -+3644697600 36 # 1 Jul 2015 -+3692217600 37 # 1 Jan 2017 -+3786825600 36 # 1 Jan 2020 (fake entry to test negative leap second) -+ -+# FIPS 180-1 hash -+# NOTE! this value has not been recomputed for this unit test file. -+#h 16edd0f0 3666784f 37db6bdd e74ced87 59af48f1 - -commit 8438f8cf3dec2f40d26198604817f1dbaf286f63 -Author: Miroslav Lichvar -Date: Wed Feb 7 15:48:43 2024 +0100 - - test: improve 113-leapsecond and 124-tai tests - - Use leapseclist instead of leapsectz and test also negative leap - seconds. Add a test for leapsectz when the date command indicates - right/UTC is available on the system and mktime() works as expected. - Check TAI offset in the server's log. - -diff --git a/test/simulation/113-leapsecond b/test/simulation/113-leapsecond -index 394440b7..63da734d 100755 ---- a/test/simulation/113-leapsecond -+++ b/test/simulation/113-leapsecond -@@ -8,54 +8,86 @@ check_config_h 'FEAT_REFCLOCK 1' || test_skip - - export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 30 2008 0:00:00' +'%s') - --leap=$[2 * 24 * 3600] - limit=$[4 * 24 * 3600] - client_start=$[2 * 3600] --server_conf="refclock SHM 0 dpoll 10 poll 10 --leapsectz right/UTC" - refclock_jitter=1e-9 --refclock_offset="(* -1.0 (equal 0.1 (max (sum 1.0) $leap) $leap))" - --for leapmode in system step slew; do -- client_conf="leapsecmode $leapmode" -- if [ $leapmode = slew ]; then -- max_sync_time=$[$leap + 12] -- else -- max_sync_time=$[$leap] -- fi -+for dir in "+1" "-1"; do -+ leap=$[2 * 24 * 3600 + 1 + $dir] -+ server_conf="refclock SHM 0 dpoll 10 poll 10 -+ leapseclist tmp/leap.list" -+ refclock_offset="(* $dir (equal 0.1 (max (sum 1.0) $leap) $leap))" -+ -+ cat > tmp/leap.list <<-EOF -+ #$ 3676924800 -+ #@ 3928521600 -+ 3345062400 33 # 1 Jan 2006 -+ 3439756800 $[33 - $dir] # 1 Jan 2009 $( -+ [ "$dir" = "+1" ] && echo -e "\n3471292800 33\n3502828800 34") -+ 3550089600 35 # 1 Jul 2012 -+ EOF -+ -+ for leapmode in system step slew; do -+ client_conf="leapsecmode $leapmode" -+ if [ $leapmode = slew ]; then -+ max_sync_time=$[2 * 24 * 3600 + 13] -+ else -+ max_sync_time=$[2 * 24 * 3600 + 1] -+ fi -+ min_sync_time=$[$max_sync_time - 2] -+ -+ run_test || test_fail -+ check_chronyd_exit || test_fail -+ check_source_selection || test_fail -+ check_packet_interval || test_fail -+ check_sync || test_fail -+ check_file_messages "System clock TAI offset set to" 1 1 log.1 || test_fail -+ check_file_messages "System clock TAI offset set to 33" 1 1 log.1 || test_fail -+ done -+ -+ client_server_options="trust" -+ client_conf="refclock SHM 0 dpoll 10 poll 10 delay 1e-3" -+ min_sync_time=$[$leap - 2] -+ max_sync_time=$[$leap] - - run_test || test_fail - check_chronyd_exit || test_fail - check_source_selection || test_fail - check_packet_interval || test_fail - check_sync || test_fail --done - --client_server_options="trust" --client_conf="refclock SHM 0 dpoll 10 poll 10 delay 1e-3" -+ client_server_options="" -+ client_conf="leapsecmode system" -+ min_sync_time=230000 -+ max_sync_time=240000 - --run_test || test_fail --check_chronyd_exit || test_fail --check_source_selection || test_fail --check_packet_interval || test_fail --check_sync || test_fail -+ for smoothmode in "" "leaponly"; do -+ server_conf="refclock SHM 0 dpoll 10 poll 10 -+ leapseclist tmp/leap.list -+ leapsecmode slew -+ smoothtime 400 0.001 $smoothmode" - --client_server_options="" --client_conf="leapsecmode system" --min_sync_time=230000 --max_sync_time=240000 -+ run_test || test_fail -+ check_chronyd_exit || test_fail -+ check_source_selection || test_fail -+ check_packet_interval || test_fail -+ check_sync || test_fail -+ done -+done - --for smoothmode in "" "leaponly"; do -+if TZ=right/UTC date -d 'Dec 31 2008 23:59:60' 2> /dev/null | grep :60; then - server_conf="refclock SHM 0 dpoll 10 poll 10 -- leapsectz right/UTC -- leapsecmode slew -- smoothtime 400 0.001 $smoothmode" -+ leapsectz right/UTC" -+ refclock_offset="(* -1 (equal 0.1 (max (sum 1.0) $leap) $leap))" -+ client_conf="leapsecmode system" -+ min_sync_time=$[$leap - 2] -+ max_sync_time=$[$leap] - - run_test || test_fail - check_chronyd_exit || test_fail - check_source_selection || test_fail - check_packet_interval || test_fail - check_sync || test_fail --done -+fi - - test_pass -diff --git a/test/simulation/124-tai b/test/simulation/124-tai -index 97064f7c..0192e10f 100755 ---- a/test/simulation/124-tai -+++ b/test/simulation/124-tai -@@ -18,10 +18,18 @@ servers=0 - refclock_offset="(+ -34 (equal 0.1 (max (sum 1.0) $leap) $leap))" - client_conf=" - refclock SHM 0 dpoll 0 poll 0 tai --leapsectz right/UTC -+leapseclist tmp/leap.list - leapsecmode ignore - maxchange 1e-3 1 0" - -+cat > tmp/leap.list <<-EOF -+ #$ 3676924800 -+ #@ 3928521600 -+ 3345062400 33 # 1 Jan 2006 -+ 3439756800 34 # 1 Jan 2009 -+ 3550089600 35 # 1 Jul 2012 -+EOF -+ - run_test || test_fail - check_chronyd_exit || test_fail - check_source_selection || test_fail -@@ -33,7 +41,7 @@ time_offset=-1000 - refclock_offset="(+ -34)" - client_conf=" - refclock SHM 0 dpoll 0 poll 0 tai --leapsectz right/UTC -+leapseclist tmp/leap.list - makestep 1 1 - maxchange 1e-3 1 0" - - -commit 307060cf0c6358bcb4028a4a25d21930669293bf -Author: Miroslav Lichvar -Date: Mon Feb 12 14:42:03 2024 +0100 - - test: avoid C99-style declaration in for loop - - This fixes compilation without the -std=c99 option with an older gcc. - -diff --git a/test/unit/leapdb.c b/test/unit/leapdb.c -index 509fc394..2344fb3d 100644 ---- a/test/unit/leapdb.c -+++ b/test/unit/leapdb.c -@@ -77,9 +77,10 @@ test_unit(void) - "leapsectz right/UTC", - "leapseclist leapdb.list" - }; -+ int i; - - CNF_Initialise(0, 0); -- for (int i = 0; i < sizeof conf / sizeof conf[0]; i++) -+ for (i = 0; i < sizeof conf / sizeof conf[0]; i++) - CNF_ParseLine(NULL, i + 1, conf[i]); - LDB_Initialise(); - - -commit 0f99aa7a922c42fb66fd11652b18741382e339e8 -Author: Miroslav Lichvar -Date: Mon Mar 11 11:59:11 2024 +0100 - - test: replace another C99-style declaration in for loop - -diff --git a/test/unit/leapdb.c b/test/unit/leapdb.c -index 2344fb3d..f2f0228f 100644 ---- a/test/unit/leapdb.c -+++ b/test/unit/leapdb.c -@@ -39,8 +39,9 @@ static void - test_leap_source(NTP_Leap (*fn)(time_t when, int *tai_offset), - int skip_fakes) - { -- int prev_tai_offset = 34; -- for (int i = 0; i < sizeof tests / sizeof tests[0]; ++i) { -+ int i, prev_tai_offset = 34; -+ -+ for (i = 0; i < sizeof tests / sizeof tests[0]; ++i) { - struct test_vector *t = tests + i; - - NTP_Leap leap; - -commit 31986485138a008c113928941c5901c850e63dba -Author: Miroslav Lichvar -Date: Wed Apr 3 11:01:44 2024 +0200 - - leapdb: fix leapsec list processing with 32-bit time_t - - A 32-bit time_t value overflows when converted to the Y1900 epoch used - in the leapsec list. Use a 64-bit variable in get_list_leap() to fix the - comparisons on systems using 32-bit time_t. - - Fixes: 53823b9f1c07 ("leapdb: support leap-seconds.list as second source") - -diff --git a/leapdb.c b/leapdb.c -index e748e001..f6b059e8 100644 ---- a/leapdb.c -+++ b/leapdb.c -@@ -110,7 +110,7 @@ get_list_leap(time_t when, int *tai_offset) - char line[1024]; - NTP_Leap ret_leap = LEAP_Normal; - int ret_tai_offset = 0, prev_lsl_tai_offset = 10; -- int64_t lsl_updated = 0, lsl_expiry = 0; -+ int64_t when1900, lsl_updated = 0, lsl_expiry = 0; - const char *leap_sec_list = CNF_GetLeapSecList(); - - if (!(f = UTI_OpenFile(NULL, leap_sec_list, NULL, 'r', 0))) { -@@ -122,7 +122,7 @@ get_list_leap(time_t when, int *tai_offset) - when = (when / (24 * 3600) + 1) * (24 * 3600); - - /* leap-seconds.list timestamps are relative to 1 Jan 1900, 00:00:00 */ -- when += LEAP_SEC_LIST_OFFSET; -+ when1900 = when + LEAP_SEC_LIST_OFFSET; - - while (fgets(line, sizeof line, f) > 0) { - int64_t lsl_when; -@@ -150,14 +150,14 @@ get_list_leap(time_t when, int *tai_offset) - if (sscanf(line, "%"SCNd64" %d", &lsl_when, &lsl_tai_offset) != 2) - goto error; - -- if (when == lsl_when) { -+ if (when1900 == lsl_when) { - if (lsl_tai_offset > prev_lsl_tai_offset) - ret_leap = LEAP_InsertSecond; - else if (lsl_tai_offset < prev_lsl_tai_offset) - ret_leap = LEAP_DeleteSecond; - /* When is rounded to the end of the day, so offset hasn't changed yet! */ - ret_tai_offset = prev_lsl_tai_offset; -- } else if (when > lsl_when) { -+ } else if (when1900 > lsl_when) { - ret_tai_offset = lsl_tai_offset; - } - -@@ -168,7 +168,7 @@ get_list_leap(time_t when, int *tai_offset) - if (!feof(f) || !lsl_updated || !lsl_expiry) - goto error; - -- if (when >= lsl_expiry) -+ if (when1900 >= lsl_expiry) - LOG(LOGS_WARN, "Leap second list %s needs update", leap_sec_list); - - goto out; - -commit b5393d24e33cf9dd3a90b519735f959a12344be7 -Author: Miroslav Lichvar -Date: Tue Jun 4 16:23:41 2024 +0200 - - test: make 124-tai more reliable - - Reported-by: Reinhard Max - -diff --git a/test/simulation/124-tai b/test/simulation/124-tai -index 0192e10f..e8c909de 100755 ---- a/test/simulation/124-tai -+++ b/test/simulation/124-tai -@@ -20,7 +20,7 @@ client_conf=" - refclock SHM 0 dpoll 0 poll 0 tai - leapseclist tmp/leap.list - leapsecmode ignore --maxchange 1e-3 1 0" -+maxchange 1e-3 10 0" - - cat > tmp/leap.list <<-EOF - #$ 3676924800 -@@ -43,7 +43,7 @@ client_conf=" - refclock SHM 0 dpoll 0 poll 0 tai - leapseclist tmp/leap.list - makestep 1 1 --maxchange 1e-3 1 0" -+maxchange 1e-3 10 0" - - run_test || test_fail - check_chronyd_exit || test_fail - -commit e48dfd722b4c299715207b78c027c651d08a5b08 -Author: Miroslav Lichvar -Date: Thu Jul 25 15:32:44 2024 +0200 - - leapdb: add explicit cast to int64_t - - Add an explicit cast to int64_t to not rely on LEAP_SEC_LIST_OFFSET - not fitting in 32-bit time_t. - -diff --git a/leapdb.c b/leapdb.c -index f6b059e8..e4b2f9f1 100644 ---- a/leapdb.c -+++ b/leapdb.c -@@ -122,7 +122,7 @@ get_list_leap(time_t when, int *tai_offset) - when = (when / (24 * 3600) + 1) * (24 * 3600); - - /* leap-seconds.list timestamps are relative to 1 Jan 1900, 00:00:00 */ -- when1900 = when + LEAP_SEC_LIST_OFFSET; -+ when1900 = (int64_t)when + LEAP_SEC_LIST_OFFSET; - - while (fgets(line, sizeof line, f) > 0) { - int64_t lsl_when; diff --git a/SOURCES/chrony-logreload.patch b/SOURCES/chrony-logreload.patch deleted file mode 100644 index b48a6bf..0000000 --- a/SOURCES/chrony-logreload.patch +++ /dev/null @@ -1,291 +0,0 @@ -commit 78707d0717db7f410b3b1e1d4ae13d5cbf863a5e -Author: Miroslav Lichvar -Date: Tue Aug 6 10:45:55 2024 +0200 - - test: extend 008-confload test - -diff --git a/test/system/008-confload b/test/system/008-confload -index 7e806988..b978c190 100755 ---- a/test/system/008-confload -+++ b/test/system/008-confload -@@ -77,7 +77,32 @@ check_chronyc_output "^[^=]* - .. 127\.123\.5\.3 *[05] 7 [^^]* - .. 127\.123\.5\.6 [^^]*$" || test_fail - -+run_chronyc "reload sources" || test_fail -+run_chronyc "reload sources" || test_fail -+ -+rm $TEST_DIR/conf5.d/{3,5,6}.sources -+echo "server 127.123.5.7" > $TEST_DIR/conf5.d/7.sources -+ -+run_chronyc "reload sources" || test_fail -+ -+run_chronyc "sources" || test_fail -+check_chronyc_output "^[^=]* -+=* -+.. 127\.123\.1\.1 [^^]* -+.. 127\.123\.1\.3 [^^]* -+.. 127\.123\.1\.4 [^^]* -+.. 127\.123\.3\.1 [^^]* -+.. 127\.123\.2\.2 [^^]* -+.. 127\.123\.2\.3 [^^]* -+.. 127\.123\.4\.4 [^^]* -+.. 127\.123\.1\.2 *[05] 6 [^^]* -+.. 127\.123\.5\.2 *[05] 5 [^^]* -+.. 127\.123\.5\.7 [^^]*$" || test_fail -+ -+run_chronyc "reload sources" || test_fail -+ - stop_chronyd || test_fail --check_chronyd_message_count "Could not add source" 1 1 || test_fail -+check_chronyd_message_count "Could not add source.*\.5\.5.*in use" 3 3 || test_fail -+check_chronyd_message_count "Could not add source" 3 3 || test_fail - - test_pass - -commit 3cac849bbfdc02625969cb721207d5436dc03ee4 -Author: Miroslav Lichvar -Date: Tue Aug 6 11:28:26 2024 +0200 - - conf: merge ntp_source_ids with ntp_sources - - Keep the configuration IDs of sources loaded from sourcedir in the - NTP_Source structure itself to simplify the code. - - (Rebased to 4.5) - -diff --git a/conf.c b/conf.c -index 146389aa..dad874b0 100644 ---- a/conf.c -+++ b/conf.c -@@ -287,15 +287,14 @@ typedef struct { - NTP_Source_Type type; - int pool; - CPS_NTP_Source params; -+ uint32_t conf_id; - } NTP_Source; - - /* Array of NTP_Source */ - static ARR_Instance ntp_sources; - /* Array of (char *) */ - static ARR_Instance ntp_source_dirs; --/* Array of uint32_t corresponding to ntp_sources (for sourcedirs reload) */ --static ARR_Instance ntp_source_ids; --/* Flag indicating ntp_sources and ntp_source_ids are used for sourcedirs */ -+/* Flag indicating ntp_sources is used for sourcedirs after config load */ - static int conf_ntp_sources_added = 0; - - /* Array of RefclockParameters */ -@@ -396,7 +395,6 @@ CNF_Initialise(int r, int client_only) - init_sources = ARR_CreateInstance(sizeof (IPAddr)); - ntp_sources = ARR_CreateInstance(sizeof (NTP_Source)); - ntp_source_dirs = ARR_CreateInstance(sizeof (char *)); -- ntp_source_ids = ARR_CreateInstance(sizeof (uint32_t)); - refclock_sources = ARR_CreateInstance(sizeof (RefclockParameters)); - broadcasts = ARR_CreateInstance(sizeof (NTP_Broadcast_Destination)); - -@@ -456,7 +454,6 @@ CNF_Finalise(void) - ARR_DestroyInstance(init_sources); - ARR_DestroyInstance(ntp_sources); - ARR_DestroyInstance(ntp_source_dirs); -- ARR_DestroyInstance(ntp_source_ids); - ARR_DestroyInstance(refclock_sources); - ARR_DestroyInstance(broadcasts); - -@@ -825,6 +822,8 @@ parse_source(char *line, char *type, int fatal) - } - - source.params.name = Strdup(source.params.name); -+ source.conf_id = 0; -+ - ARR_AppendElement(ntp_sources, &source); - } - -@@ -1678,7 +1677,6 @@ reload_source_dirs(void) - { - NTP_Source *prev_sources, *new_sources, *source; - unsigned int i, j, prev_size, new_size, unresolved; -- uint32_t *prev_ids, *new_ids; - char buf[MAX_LINE_LENGTH]; - NSR_Status s; - int d, pass; -@@ -1687,13 +1685,9 @@ reload_source_dirs(void) - if (!conf_ntp_sources_added) - return; - -- prev_size = ARR_GetSize(ntp_source_ids); -- if (ARR_GetSize(ntp_sources) != prev_size) -- assert(0); -+ prev_size = ARR_GetSize(ntp_sources); - -- /* Save the current sources and their configuration IDs */ -- prev_ids = MallocArray(uint32_t, prev_size); -- memcpy(prev_ids, ARR_GetElements(ntp_source_ids), prev_size * sizeof (prev_ids[0])); -+ /* Save the current sources */ - prev_sources = MallocArray(NTP_Source, prev_size); - memcpy(prev_sources, ARR_GetElements(ntp_sources), prev_size * sizeof (prev_sources[0])); - -@@ -1711,8 +1705,6 @@ reload_source_dirs(void) - - new_size = ARR_GetSize(ntp_sources); - new_sources = ARR_GetElements(ntp_sources); -- ARR_SetSize(ntp_source_ids, new_size); -- new_ids = ARR_GetElements(ntp_source_ids); - unresolved = 0; - - LOG_SetContext(LOGC_SourceFile); -@@ -1728,14 +1720,14 @@ reload_source_dirs(void) - - /* Remove missing sources before adding others to avoid conflicts */ - if (pass == 0 && d < 0 && prev_sources[i].params.name[0] != '\0') { -- NSR_RemoveSourcesById(prev_ids[i]); -+ NSR_RemoveSourcesById(prev_sources[i].conf_id); - } - - /* Add new sources */ - if (pass == 1 && d > 0) { - source = &new_sources[j]; - s = NSR_AddSourceByName(source->params.name, source->params.port, source->pool, -- source->type, &source->params.params, &new_ids[j]); -+ source->type, &source->params.params, &source->conf_id); - - if (s == NSR_UnresolvedName) { - unresolved++; -@@ -1750,7 +1742,7 @@ reload_source_dirs(void) - - /* Keep unchanged sources */ - if (pass == 1 && d == 0) -- new_ids[j] = prev_ids[i]; -+ new_sources[j].conf_id = prev_sources[i].conf_id; - } - } - -@@ -1759,7 +1751,6 @@ reload_source_dirs(void) - for (i = 0; i < prev_size; i++) - Free(prev_sources[i].params.name); - Free(prev_sources); -- Free(prev_ids); - - if (unresolved > 0) - NSR_ResolveSources(); -@@ -1858,7 +1849,6 @@ CNF_AddSources(void) - - /* The arrays will be used for sourcedir (re)loading */ - ARR_SetSize(ntp_sources, 0); -- ARR_SetSize(ntp_source_ids, 0); - conf_ntp_sources_added = 1; - - reload_source_dirs(); - -commit 8126dbd2de30957de32ce3e55ce367b7145a4c33 -Author: Miroslav Lichvar -Date: Tue Aug 6 12:56:39 2024 +0200 - - conf: save source status in sourcedir reload - - Save the NSR status when adding a source from a sourcedir and don't - hide sources that failed the addition by clearing their name. - - (Rebased to 4.5) - -diff --git a/conf.c b/conf.c -index dad874b0..6020e880 100644 ---- a/conf.c -+++ b/conf.c -@@ -287,6 +287,7 @@ typedef struct { - NTP_Source_Type type; - int pool; - CPS_NTP_Source params; -+ NSR_Status status; - uint32_t conf_id; - } NTP_Source; - -@@ -822,6 +823,7 @@ parse_source(char *line, char *type, int fatal) - } - - source.params.name = Strdup(source.params.name); -+ source.status = NSR_NoSuchSource; - source.conf_id = 0; - - ARR_AppendElement(ntp_sources, &source); -@@ -1719,30 +1721,30 @@ reload_source_dirs(void) - d = i < prev_size ? -1 : 1; - - /* Remove missing sources before adding others to avoid conflicts */ -- if (pass == 0 && d < 0 && prev_sources[i].params.name[0] != '\0') { -+ if (pass == 0 && d < 0 && prev_sources[i].status == NSR_Success) { - NSR_RemoveSourcesById(prev_sources[i].conf_id); - } - -- /* Add new sources */ -- if (pass == 1 && d > 0) { -+ /* Add new sources and sources that could not be added before */ -+ if (pass == 1 && (d > 0 || (d == 0 && prev_sources[i].status != NSR_Success))) { - source = &new_sources[j]; - s = NSR_AddSourceByName(source->params.name, source->params.port, source->pool, - source->type, &source->params.params, &source->conf_id); -+ source->status = s; - - if (s == NSR_UnresolvedName) { - unresolved++; - } else if (s != NSR_Success) { - LOG(LOGS_ERR, "Could not add source %s : %s", - source->params.name, NSR_StatusToString(s)); -- -- /* Mark the source as not present */ -- source->params.name[0] = '\0'; - } - } - - /* Keep unchanged sources */ -- if (pass == 1 && d == 0) -+ if (pass == 1 && d == 0) { -+ new_sources[j].status = prev_sources[i].status; - new_sources[j].conf_id = prev_sources[i].conf_id; -+ } - } - } - - -commit 7cd5d065fc17a0ec871df2ffdc74caf6d16d9f6a -Author: Miroslav Lichvar -Date: Tue Aug 6 13:05:26 2024 +0200 - - conf: don't repeat error message when adding sourcedir source - - When a source from a configured sourcedir cannot be added (e.g. it is a - duplicate of another source), log the error message only on the first - attempt adding the source, until the source is removed and added to a - sourcedir again. - - This avoids spamming of the system log with error messages if the - reload sources command is called frequently (e.g. from a DHCP renewal - networking script). - -diff --git a/conf.c b/conf.c -index 6020e880..522e235a 100644 ---- a/conf.c -+++ b/conf.c -@@ -1734,7 +1734,7 @@ reload_source_dirs(void) - - if (s == NSR_UnresolvedName) { - unresolved++; -- } else if (s != NSR_Success) { -+ } else if (s != NSR_Success && (d > 0 || s != prev_sources[i].status)) { - LOG(LOGS_ERR, "Could not add source %s : %s", - source->params.name, NSR_StatusToString(s)); - } -diff --git a/test/system/008-confload b/test/system/008-confload -index b978c190..b107d709 100755 ---- a/test/system/008-confload -+++ b/test/system/008-confload -@@ -102,7 +102,7 @@ check_chronyc_output "^[^=]* - run_chronyc "reload sources" || test_fail - - stop_chronyd || test_fail --check_chronyd_message_count "Could not add source.*\.5\.5.*in use" 3 3 || test_fail --check_chronyd_message_count "Could not add source" 3 3 || test_fail -+check_chronyd_message_count "Could not add source.*\.5\.5.*in use" 1 1 || test_fail -+check_chronyd_message_count "Could not add source" 1 1 || test_fail - - test_pass diff --git a/SOURCES/chrony-refclkreach.patch b/SOURCES/chrony-refclkreach.patch new file mode 100644 index 0000000..9731d53 --- /dev/null +++ b/SOURCES/chrony-refclkreach.patch @@ -0,0 +1,226 @@ +commit b9b338a8df23927d8104f41ecb21baa3558de0cd +Author: Miroslav Lichvar +Date: Thu Oct 31 14:41:19 2024 +0100 + + refclock: rework update of reachability + + Update the reachability register of a refclock source by 1 if a valid + measurement is received by the drivers between source polls, and not + only when it is accumulated to sourcestats, similarly to how + reachability works with NTP sources. + + This avoids drops in the reported reachability when a PHC refclock is + dropping samples due to significant changes in the measured delay (e.g. + due to high PCIe load), or a PPS refclock dropping samples due to failed + lock. + +diff --git a/doc/chronyc.adoc b/doc/chronyc.adoc +index 935f1da9..dea93c9f 100644 +--- a/doc/chronyc.adoc ++++ b/doc/chronyc.adoc +@@ -364,9 +364,12 @@ a measurement is being made every 64 seconds. *chronyd* automatically varies + the polling rate in response to prevailing conditions. + *Reach*::: + This shows the source's reachability register printed as an octal number. The +-register has 8 bits and is updated on every received or missed packet from +-the source. A value of 377 indicates that a valid reply was received for all +-from the last eight transmissions. ++register has 8 bits. It is shifted to left by one bit with each poll and it is ++updated by 1 when a valid NTP response, or just a sample in case of a reference ++clock, is received from the source. A value of 377 indicates that a valid ++response or sample was received for all of the last 8 polls. Note that samples ++can be dropped if they are not considered good enough for synchronisation, but ++the reachability register will still have 1s for their polls. + *LastRx*::: + This column shows how long ago the last good sample (which is shown in the next + column) was received from the source. Measurements that failed some tests are +diff --git a/refclock.c b/refclock.c +index 22d775a5..d14560fa 100644 +--- a/refclock.c ++++ b/refclock.c +@@ -63,6 +63,7 @@ struct RCL_Instance_Record { + int driver_poll; + int driver_polled; + int poll; ++ int reached; + int leap_status; + int local; + int pps_forced; +@@ -175,6 +176,7 @@ RCL_AddRefclock(RefclockParameters *params) + inst->driver_poll = params->driver_poll; + inst->poll = params->poll; + inst->driver_polled = 0; ++ inst->reached = 0; + inst->leap_status = LEAP_Normal; + inst->local = params->local; + inst->pps_forced = params->pps_forced; +@@ -665,6 +667,12 @@ RCL_AddCookedPulse(RCL_Instance instance, struct timespec *cooked_time, + return 1; + } + ++void ++RCL_UpdateReachability(RCL_Instance instance) ++{ ++ instance->reached++; ++} ++ + double + RCL_GetPrecision(RCL_Instance instance) + { +@@ -792,6 +800,9 @@ poll_timeout(void *arg) + if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) { + inst->driver_polled = 0; + ++ SRC_UpdateReachability(inst->source, inst->reached > 0); ++ inst->reached = 0; ++ + if (SPF_GetFilteredSample(inst->filter, &sample)) { + double local_freq, local_offset; + struct timespec local_ref_time; +@@ -807,7 +818,6 @@ poll_timeout(void *arg) + inst->leap_status = LEAP_Unsynchronised; + } + +- SRC_UpdateReachability(inst->source, 1); + SRC_UpdateStatus(inst->source, stratum, inst->leap_status); + SRC_AccumulateSample(inst->source, &sample); + SRC_SelectSource(inst->source); +@@ -816,8 +826,6 @@ poll_timeout(void *arg) + follow_local(inst, &local_ref_time, local_freq, local_offset); + + log_sample(inst, &sample.time, 1, 0, 0.0, sample.offset, sample.peer_dispersion); +- } else { +- SRC_UpdateReachability(inst->source, 0); + } + } + +diff --git a/refclock.h b/refclock.h +index 40c852de..5fdbf9c7 100644 +--- a/refclock.h ++++ b/refclock.h +@@ -81,6 +81,7 @@ extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, + extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second); + extern int RCL_AddCookedPulse(RCL_Instance instance, struct timespec *cooked_time, + double second, double dispersion, double raw_correction); ++extern void RCL_UpdateReachability(RCL_Instance instance); + extern double RCL_GetPrecision(RCL_Instance instance); + extern int RCL_GetDriverPoll(RCL_Instance instance); + +diff --git a/refclock_phc.c b/refclock_phc.c +index e12f2258..6c0914f6 100644 +--- a/refclock_phc.c ++++ b/refclock_phc.c +@@ -154,6 +154,8 @@ static void process_ext_pulse(RCL_Instance instance, struct timespec *phc_ts) + } + phc->last_extts = *phc_ts; + ++ RCL_UpdateReachability(instance); ++ + if (!HCL_CookTime(phc->clock, phc_ts, &local_ts, &local_err)) + return; + +@@ -204,6 +206,9 @@ static int phc_poll(RCL_Instance instance) + if (n_readings < 1) + return 0; + ++ if (!phc->extpps) ++ RCL_UpdateReachability(instance); ++ + if (!HCL_ProcessReadings(phc->clock, n_readings, readings, &phc_ts, &sys_ts, &phc_err)) + return 0; + +diff --git a/refclock_pps.c b/refclock_pps.c +index 880c13fc..f00b7ccb 100644 +--- a/refclock_pps.c ++++ b/refclock_pps.c +@@ -143,6 +143,8 @@ static int pps_poll(RCL_Instance instance) + + pps->last_seq = seq; + ++ RCL_UpdateReachability(instance); ++ + return RCL_AddPulse(instance, &ts, 1.0e-9 * ts.tv_nsec); + } + +diff --git a/refclock_shm.c b/refclock_shm.c +index ee13e871..22e51820 100644 +--- a/refclock_shm.c ++++ b/refclock_shm.c +@@ -109,6 +109,8 @@ static int shm_poll(RCL_Instance instance) + + shm->valid = 0; + ++ RCL_UpdateReachability(instance); ++ + receive_ts.tv_sec = t.receiveTimeStampSec; + clock_ts.tv_sec = t.clockTimeStampSec; + +diff --git a/refclock_sock.c b/refclock_sock.c +index 2da57ef5..49cf3559 100644 +--- a/refclock_sock.c ++++ b/refclock_sock.c +@@ -129,6 +129,8 @@ static void read_sample(int sockfd, int event, void *anything) + UTI_TimevalToTimespec(&sample.tv, &sys_ts); + UTI_NormaliseTimespec(&sys_ts); + ++ RCL_UpdateReachability(instance); ++ + if (!UTI_IsTimeOffsetSane(&sys_ts, sample.offset)) + return; + +diff --git a/test/simulation/106-refclock b/test/simulation/106-refclock +index dedab9b8..3793bd86 100755 +--- a/test/simulation/106-refclock ++++ b/test/simulation/106-refclock +@@ -114,6 +114,32 @@ Root delay : 0\.000000001 seconds + rm -f tmp/refclocks.log + fi + ++export CLKNETSIM_PHC_JITTER_OFF=$[2 * 25 * 492] ++export CLKNETSIM_PHC_JITTER_ON=$[2 * 25 * 8] ++export CLKNETSIM_PHC_JITTER=1e-6 ++refclock_offset=0.0 ++refclock_jitter=1e-9 ++min_sync_time=5 ++max_sync_time=7 ++time_max_limit=1e-7 ++time_rms_limit=1e-8 ++client_conf="refclock PHC /dev/ptp0:nocrossts poll 0 ++logdir tmp ++log refclocks" ++chronyc_start=500 ++chronyc_conf="sources" ++ ++run_test || test_fail ++check_chronyd_exit || test_fail ++check_source_selection || test_fail ++check_sync || test_fail ++check_chronyc_output "^MS.* ++=* ++#\* PHC0 0 0 377 8 .*$" || test_fail ++ ++unset CLKNETSIM_PHC_JITTER_OFF ++unset CLKNETSIM_PHC_JITTER_ON ++export CLKNETSIM_PHC_JITTER=1e-7 + refclock_offset="(+ 0.399 (sum 1e-3))" + refclock_jitter=1e-6 + servers=1 +diff -up chrony/doc/chronyc.man.orig chrony/doc/chronyc.man +--- chrony/doc/chronyc.man.in.orig 2024-11-06 12:07:50.555216174 +0100 ++++ chrony/doc/chronyc.man.in 2024-11-06 12:07:58.131217759 +0100 +@@ -535,9 +535,12 @@ the polling rate in response to prevaili + \fBReach\fP + .RS 4 + This shows the source\(cqs reachability register printed as an octal number. The +-register has 8 bits and is updated on every received or missed packet from +-the source. A value of 377 indicates that a valid reply was received for all +-from the last eight transmissions. ++register has 8 bits. It is shifted to left by one bit with each poll and it is ++updated by 1 when a valid NTP response, or just a sample in case of a reference ++clock, is received from the source. A value of 377 indicates that a valid ++response or sample was received for all of the last 8 polls. Note that samples ++can be dropped if they are not considered good enough for synchronisation, but ++the reachability register will still have 1s for their polls. + .RE + .sp + \fBLastRx\fP diff --git a/SOURCES/chrony-reload.patch b/SOURCES/chrony-reload.patch deleted file mode 100644 index b8ac742..0000000 --- a/SOURCES/chrony-reload.patch +++ /dev/null @@ -1,86 +0,0 @@ -commit f49be7f06343ee27fff2950937d7f6742f53976f -Author: Miroslav Lichvar -Date: Tue Mar 12 14:30:27 2024 +0100 - - conf: don't load sourcedir during initstepslew and RTC init - - If the reload sources command was received in the chronyd start-up - sequence with initstepslew and/or RTC init (-s option), the sources - loaded from sourcedirs caused a crash due to failed assertion after - adding sources specified in the config. - - Ignore the reload sources command until chronyd enters the normal - operation mode. - - Fixes: 519796de3756 ("conf: add sourcedirs directive") - -diff --git a/conf.c b/conf.c -index 6eae11c9..8849bdce 100644 ---- a/conf.c -+++ b/conf.c -@@ -298,6 +298,8 @@ static ARR_Instance ntp_sources; - static ARR_Instance ntp_source_dirs; - /* Array of uint32_t corresponding to ntp_sources (for sourcedirs reload) */ - static ARR_Instance ntp_source_ids; -+/* Flag indicating ntp_sources and ntp_source_ids are used for sourcedirs */ -+static int conf_ntp_sources_added = 0; - - /* Array of RefclockParameters */ - static ARR_Instance refclock_sources; -@@ -1689,8 +1691,12 @@ reload_source_dirs(void) - NSR_Status s; - int d, pass; - -+ /* Ignore reload command before adding configured sources */ -+ if (!conf_ntp_sources_added) -+ return; -+ - prev_size = ARR_GetSize(ntp_source_ids); -- if (prev_size > 0 && ARR_GetSize(ntp_sources) != prev_size) -+ if (ARR_GetSize(ntp_sources) != prev_size) - assert(0); - - /* Save the current sources and their configuration IDs */ -@@ -1859,7 +1865,10 @@ CNF_AddSources(void) - Free(source->params.name); - } - -+ /* The arrays will be used for sourcedir (re)loading */ - ARR_SetSize(ntp_sources, 0); -+ ARR_SetSize(ntp_source_ids, 0); -+ conf_ntp_sources_added = 1; - - reload_source_dirs(); - } -diff --git a/test/simulation/203-initreload b/test/simulation/203-initreload -new file mode 100755 -index 00000000..cf7924b8 ---- /dev/null -+++ b/test/simulation/203-initreload -@@ -0,0 +1,26 @@ -+#!/usr/bin/env bash -+ -+. ./test.common -+ -+check_config_h 'FEAT_CMDMON 1' || test_skip -+ -+# Test fix "conf: don't load sourcedir during initstepslew and RTC init" -+ -+test_start "reload during initstepslew" -+ -+client_conf="initstepslew 5 192.168.123.1 -+sourcedir tmp" -+client_server_conf="#" -+chronyc_conf="reload sources" -+chronyc_start=4 -+ -+echo 'server 192.168.123.1' > tmp/sources.sources -+ -+run_test || test_fail -+check_chronyd_exit || test_fail -+check_source_selection || test_fail -+check_sync || test_fail -+ -+check_log_messages "Added source 192\.168\.123\.1" 1 1 || test_fail -+ -+test_pass diff --git a/SOURCES/chrony-serverstats.patch b/SOURCES/chrony-serverstats.patch deleted file mode 100644 index a5131fe..0000000 --- a/SOURCES/chrony-serverstats.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit e11b518a1ffa704986fb1f1835c425844ba248ef -Author: Miroslav Lichvar -Date: Mon Jan 8 11:35:56 2024 +0100 - - ntp: fix authenticated requests in serverstats - - Fix the CLG_UpdateNtpStats() call to count requests passing the - authentication check instead of requests triggering a KoD response - (i.e. NTS NAK). - -diff --git a/ntp_core.c b/ntp_core.c -index 023e60b2..35801744 100644 ---- a/ntp_core.c -+++ b/ntp_core.c -@@ -2736,7 +2736,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a - CLG_DisableNtpTimestamps(&ntp_rx); - } - -- CLG_UpdateNtpStats(kod != 0 && info.auth.mode != NTP_AUTH_NONE && -+ CLG_UpdateNtpStats(kod == 0 && info.auth.mode != NTP_AUTH_NONE && - info.auth.mode != NTP_AUTH_MSSNTP, - rx_ts->source, interleaved ? tx_ts->source : NTP_TS_DAEMON); - -diff --git a/test/system/010-nts b/test/system/010-nts -index 8d92bbc8..b215efa3 100755 ---- a/test/system/010-nts -+++ b/test/system/010-nts -@@ -45,6 +45,11 @@ check_chronyc_output "^Name/IP address Mode KeyID Type KLen Last Atm - ========================================================================= - 127\.0\.0\.1 NTS 1 (30|15) (128|256) [0-9] 0 0 [78] ( 64|100)$" || test_fail - -+run_chronyc "serverstats" || test_fail -+check_chronyc_output "NTS-KE connections accepted: 1 -+NTS-KE connections dropped : 0 -+Authenticated NTP packets : [1-9][0-9]*" || test_fail -+ - stop_chronyd || test_fail - check_chronyd_messages || test_fail - check_chronyd_files || test_fail diff --git a/SPECS/chrony.spec b/SPECS/chrony.spec index 421c98d..acc8e4f 100644 --- a/SPECS/chrony.spec +++ b/SPECS/chrony.spec @@ -1,5 +1,5 @@ %global _hardened_build 1 -%global clknetsim_ver 5d1dc0 +%global clknetsim_ver 40bb97 %bcond_without debug %bcond_without nts @@ -8,8 +8,8 @@ %endif Name: chrony -Version: 4.5 -Release: 3%{?dist} +Version: 4.6.1 +Release: 1%{?dist} Summary: An NTP client/server License: GPLv2 @@ -29,16 +29,10 @@ Patch1: chrony-nm-dispatcher-dhcp.patch Patch2: chrony-keys.patch # revert some hardening options in service files Patch3: chrony-services.patch -# fix serverstats to correctly count authenticated packets -Patch4: chrony-serverstats.patch -# fix crash on reload command during start -Patch5: chrony-reload.patch -# don't repeat error log messages when reloading sourcedir -Patch6: chrony-logreload.patch -# add support for leap-seconds.list file -Patch7: chrony-leaplist.patch -# update asciidoctor-generated man page -Patch8: chrony-leaplist-man.patch +# revert upstream changes in packaged configuration examples +Patch4: chrony-defconfig.patch +# keep PHC refclock reachable when dropping samples due to high delay +Patch5: chrony-refclkreach.patch BuildRequires: gnutls-devel libcap-devel libedit-devel pps-tools-devel BuildRequires: gcc gcc-c++ make bison systemd gnupg2 @@ -72,11 +66,8 @@ service to other computers in the network. %patch1 -p1 -b .nm-dispatcher-dhcp %patch2 -p1 -b .keys %patch3 -p1 -b .services -%patch4 -p1 -b .serverstats +%patch4 -p1 -b .defconfig %patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 %{?gitpatch: echo %{version}-%{gitpatch} > version.txt} @@ -229,6 +220,14 @@ fi %dir %attr(750,chrony,chrony) %{_localstatedir}/log/chrony %changelog +* Wed Nov 06 2024 Miroslav Lichvar 4.6.1-1 +- update to 4.6.1 (RHEL-61877) +- keep PHC refclock reachable when dropping samples due to high delay + (RHEL-65421) + +* Thu Sep 05 2024 Miroslav Lichvar 4.6-1 +- update to 4.6 (RHEL-56964) + * Thu Aug 08 2024 Miroslav Lichvar 4.5-3 - don't repeat error log messages when reloading sourcedir (RHEL-51786) - add support for leap-seconds.list file (RHEL-53484)