Import from AlmaLinux stable repository

This commit is contained in:
eabdullin 2025-12-04 11:26:17 +00:00
parent f7e9fbfab1
commit af2bce4f0f
12 changed files with 1320 additions and 68 deletions

View File

@ -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
c29c27ef95a3c80737a97ae6e3ee386e1af625de SOURCES/clknetsim-cdd694.tar.gz

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/chrony-4.5.tar.gz
SOURCES/clknetsim-5d1dc0.tar.gz
SOURCES/chrony-4.6.1.tar.gz
SOURCES/clknetsim-cdd694.tar.gz

View File

@ -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-----

View File

@ -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-----

View File

@ -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

View File

@ -0,0 +1,55 @@
commit b889627998ba584528d1c1145a212fb2b97e5289
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 27 10:04:41 2025 +0100
doc: improve description of refresh directive
diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc
index 7ccdd20c..eb00e029 100644
--- a/doc/chrony.conf.adoc
+++ b/doc/chrony.conf.adoc
@@ -941,14 +941,15 @@ time, assuming the first update corrects the clock and later checks can work
with correct time.
[[refresh]]*refresh* _interval_::
-This directive specifies the interval (in seconds) between refreshing IP
-addresses of NTP sources specified by hostname. If the hostname no longer
+This directive specifies the minimum interval (in seconds) between refreshing
+IP addresses of NTP sources specified by hostname. If the hostname no longer
resolves to the currently used address, it will be replaced with one of the new
addresses to avoid using a server which is no longer intended for service, even
if it is still responding correctly and would not be replaced as unreachable.
-Only one source is refreshed at a time. The default value is 1209600 (2 weeks)
-and the maximum value is 2^31-1 (68 years). A value of 0 disables the periodic
-refreshment.
+Only one source is refreshed at a time and only when a valid response is
+received (unreachable sources are replaced independently). The default value is
+1209600 (2 weeks) and the maximum value is 2^31-1 (68 years). A value of 0
+disables the periodic refreshment.
+
The <<chronyc.adoc#refresh,*refresh*>> command can be used to refresh all
sources immediately.
diff -up chrony-4.6.1/doc/chrony.conf.man.in.docrefresh chrony-4.6.1/doc/chrony.conf.man.in
--- chrony-4.6.1/doc/chrony.conf.man.in.docrefresh 2025-05-15 17:04:33.824077026 +0200
+++ chrony-4.6.1/doc/chrony.conf.man.in 2025-05-15 17:04:53.308070453 +0200
@@ -1270,14 +1270,15 @@ with correct time.
.sp
\fBrefresh\fP \fIinterval\fP
.RS 4
-This directive specifies the interval (in seconds) between refreshing IP
-addresses of NTP sources specified by hostname. If the hostname no longer
+This directive specifies the minimum interval (in seconds) between refreshing
+IP addresses of NTP sources specified by hostname. If the hostname no longer
resolves to the currently used address, it will be replaced with one of the new
addresses to avoid using a server which is no longer intended for service, even
if it is still responding correctly and would not be replaced as unreachable.
-Only one source is refreshed at a time. The default value is 1209600 (2 weeks)
-and the maximum value is 2^31\-1 (68 years). A value of 0 disables the periodic
-refreshment.
+Only one source is refreshed at a time and only when a valid response is
+received (unreachable sources are replaced independently). The default value is
+1209600 (2 weeks) and the maximum value is 2^31\-1 (68 years). A value of 0
+disables the periodic refreshment.
.sp
The \fBrefresh\fP command can be used to refresh all
sources immediately.

View File

@ -0,0 +1,612 @@
commit 620210218c4d2e9634035b3c3d01b0a329708111
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Mar 3 15:48:37 2025 +0100
sources: refactor logging of source-specific selection status
Move logging of falsetickers and system peers to the mark_source()
function. Use an array to flag already logged messages in preparation
for logging of other status. Support variable number of arguments in the
logging functions.
diff --git a/sources.c b/sources.c
index e292e4d6..bfb1c45b 100644
--- a/sources.c
+++ b/sources.c
@@ -66,7 +66,7 @@ struct SelectInfo {
/* This enum contains the flag values that are used to label
each source */
typedef enum {
- SRC_OK, /* OK so far, not a final status! */
+ SRC_OK = 0, /* OK so far, not a final status! */
SRC_UNSELECTABLE, /* Has noselect option set */
SRC_BAD_STATS, /* Doesn't have valid stats data */
SRC_UNSYNCHRONISED, /* Provides samples, but not synchronised */
@@ -144,9 +144,9 @@ struct SRC_Instance_Record {
/* Flag indicating the source has a leap second vote */
int leap_vote;
- /* Flag indicating the source was already reported as
- a falseticker since the last selection change */
- int reported_falseticker;
+ /* Flags indicating which status was already reported for
+ the source since the last change of the system peer */
+ char reported_status[SRC_SELECTED + 1];
};
/* ================================================== */
@@ -360,8 +360,8 @@ SRC_ResetInstance(SRC_Instance instance)
instance->stratum = 0;
instance->leap = LEAP_Unsynchronised;
instance->leap_vote = 0;
- instance->reported_falseticker = 0;
+ memset(instance->reported_status, 0, sizeof (instance->reported_status));
memset(&instance->sel_info, 0, sizeof (instance->sel_info));
SST_ResetInstance(instance->stats);
@@ -620,20 +620,45 @@ update_sel_options(void)
/* ================================================== */
+FORMAT_ATTRIBUTE_PRINTF(2, 3)
static void
-log_selection_message(LOG_Severity severity, const char *format, const char *arg)
+log_selection_message(LOG_Severity severity, const char *format, ...)
{
+ char buf[256];
+ va_list ap;
+
if (REF_GetMode() != REF_ModeNormal)
return;
- LOG(severity, format, arg);
+
+ va_start(ap, format);
+ vsnprintf(buf, sizeof (buf), format, ap);
+ va_end(ap);
+
+ LOG(severity, "%s", buf);
}
/* ================================================== */
+FORMAT_ATTRIBUTE_PRINTF(3, 4)
static void
-log_selection_source(LOG_Severity severity, const char *format, SRC_Instance inst)
+log_selection_source(LOG_Severity severity, SRC_Instance inst, const char *format, ...)
{
- char buf[320], *name, *ntp_name;
+ char buf[320], buf2[256], *name, *ntp_name, *s;
+ va_list ap;
+
+ if (REF_GetMode() != REF_ModeNormal)
+ return;
+
+ va_start(ap, format);
+ vsnprintf(buf2, sizeof (buf2), format, ap);
+ va_end(ap);
+
+ /* Replace ## with %s in the formatted string to be the source name */
+ s = strstr(buf2, "##");
+ if (!s || strchr(buf2, '%'))
+ return;
+ s[0] = '%';
+ s[1] = 's';
name = source_to_string(inst);
ntp_name = inst->type == SRC_NTP ? NSR_GetName(inst->ip_addr) : NULL;
@@ -643,7 +668,9 @@ log_selection_source(LOG_Severity severity, const char *format, SRC_Instance ins
else
snprintf(buf, sizeof (buf), "%s", name);
- log_selection_message(severity, format, buf);
+ LOG(severity, buf2, buf);
+
+ inst->reported_status[inst->status] = 1;
}
/* ================================================== */
@@ -686,7 +713,7 @@ source_to_string(SRC_Instance inst)
/* ================================================== */
static void
-mark_source(SRC_Instance inst, SRC_Status status)
+set_source_status(SRC_Instance inst, SRC_Status status)
{
struct timespec now;
@@ -731,6 +758,30 @@ mark_source(SRC_Instance inst, SRC_Status status)
/* ================================================== */
+static void
+mark_source(SRC_Instance inst, SRC_Status status)
+{
+ set_source_status(inst, status);
+
+ if (status < SRC_OK || status >= sizeof (inst->reported_status))
+ assert(0);
+
+ if (!inst->reported_status[status]) {
+ switch (status) {
+ case SRC_FALSETICKER:
+ log_selection_source(LOGS_WARN, inst, "Detected falseticker ##");
+ break;
+ case SRC_SELECTED:
+ log_selection_source(LOGS_INFO, inst, "Selected source ##");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/* ================================================== */
+
static void
mark_ok_sources(SRC_Status status)
{
@@ -739,7 +790,8 @@ mark_ok_sources(SRC_Status status)
for (i = 0; i < n_sources; i++) {
if (sources[i]->status != SRC_OK)
continue;
- mark_source(sources[i], status);
+ /* Don't log the status in this case (multiple sources at once) */
+ set_source_status(sources[i], status);
}
}
@@ -1161,7 +1213,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
/* Could not even get half the reachable (trusted) sources to agree */
if (!reported_no_majority) {
- log_selection_message(LOGS_WARN, "Can't synchronise: no majority", NULL);
+ log_selection_message(LOGS_WARN, "Can't synchronise: no majority");
reported_no_majority = 1;
report_selection_loss = 0;
}
@@ -1212,10 +1264,6 @@ SRC_SelectSource(SRC_Instance updated_inst)
sel_req_source = 0;
} else {
mark_source(sources[i], SRC_FALSETICKER);
- if (!sources[i]->reported_falseticker) {
- log_selection_source(LOGS_WARN, "Detected falseticker %s", sources[i]);
- sources[i]->reported_falseticker = 1;
- }
}
}
@@ -1335,13 +1383,12 @@ SRC_SelectSource(SRC_Instance updated_inst)
}
selected_source_index = max_score_index;
- log_selection_source(LOGS_INFO, "Selected source %s", sources[selected_source_index]);
/* New source has been selected, reset all scores */
for (i = 0; i < n_sources; i++) {
sources[i]->sel_score = 1.0;
sources[i]->distant = 0;
- sources[i]->reported_falseticker = 0;
+ memset(sources[i]->reported_status, 0, sizeof (sources[i]->reported_status));
}
reported_no_majority = 0;
commit 52237b7d0da75fcd750c5d5ee80e87b97474f7fd
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed Mar 5 10:45:20 2025 +0100
sources: warn about sources exceeding maxdistance or maxjitter
Log a warning message if a source is rejected in the source selecting
due to exceeding the maxdistance or maxjitter limit to make it more
obvious when synchronization is failing for this reason. Delay the
message until the reachability register is full (8 updates), or a
replacement of the source is attempted.
diff --git a/sources.c b/sources.c
index bfb1c45b..2ba595b5 100644
--- a/sources.c
+++ b/sources.c
@@ -768,6 +768,20 @@ mark_source(SRC_Instance inst, SRC_Status status)
if (!inst->reported_status[status]) {
switch (status) {
+ case SRC_BAD_DISTANCE:
+ if (inst->reachability_size < SOURCE_REACH_BITS && inst->bad < BAD_HANDLE_THRESHOLD)
+ break;
+ log_selection_source(LOGS_WARN, inst,
+ "Root distance of ## exceeds maxdistance of %.3f seconds",
+ max_distance);
+ break;
+ case SRC_JITTERY:
+ if (inst->reachability_size < SOURCE_REACH_BITS && inst->bad < BAD_HANDLE_THRESHOLD)
+ break;
+ log_selection_source(LOGS_WARN, inst,
+ "Jitter of ## exceeds maxjitter of %.3f seconds",
+ max_jitter);
+ break;
case SRC_FALSETICKER:
log_selection_source(LOGS_WARN, inst, "Detected falseticker ##");
break;
commit 1c06925d439d8699cc52df71a7a4e809b5b7348f
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Mar 6 12:46:09 2025 +0100
sources: improve no majority log message
Add the number of sources that form an agreement (overlapping
intervals), if at least two agree with each other, and number of
reachable sources to the "Can't synchronize: no majority" log message to
better explain why synchronization is failing and hint that adding more
sources might help.
diff --git a/sources.c b/sources.c
index 2ba595b5..3b1766be 100644
--- a/sources.c
+++ b/sources.c
@@ -1222,12 +1222,23 @@ SRC_SelectSource(SRC_Instance updated_inst)
assert(depth == 0 && trust_depth == 0);
assert(2 * n_sel_sources == n_endpoints);
- if ((best_trust_depth == 0 && best_depth <= n_sel_sources / 2) ||
- (best_trust_depth > 0 && best_trust_depth <= n_sel_trust_sources / 2)) {
+ if (best_trust_depth > 0) {
+ best_depth = best_trust_depth;
+ n_sel_sources = n_sel_trust_sources;
+ }
+
+ if (best_depth <= n_sel_sources / 2) {
/* Could not even get half the reachable (trusted) sources to agree */
if (!reported_no_majority) {
- log_selection_message(LOGS_WARN, "Can't synchronise: no majority");
+ if (best_depth < 2)
+ log_selection_message(LOGS_WARN, "%s (no agreement among %d %ssources)",
+ "Can't synchronise: no majority", n_sel_sources,
+ best_trust_depth > 0 ? "trusted " : "");
+ else
+ log_selection_message(LOGS_WARN, "%s (only %d of %d %ssources agree)",
+ "Can't synchronise: no majority", best_depth,
+ n_sel_sources, best_trust_depth > 0 ? "trusted " : "");
reported_no_majority = 1;
report_selection_loss = 0;
}
diff --git a/test/simulation/009-sourceselection b/test/simulation/009-sourceselection
index 547c376c..139b6aa2 100755
--- a/test/simulation/009-sourceselection
+++ b/test/simulation/009-sourceselection
@@ -24,6 +24,12 @@ for falsetickers in 3 4; do
# These check are expected to fail
check_source_selection && test_fail
check_sync && test_fail
+
+ if [ $falsetickers = 3 ]; then
+ check_log_messages "Can't synchronise: no majority (only 2 of 5 sources agree)" 1 1 || test_fail
+ else
+ check_log_messages "Can't synchronise: no majority (no agreement among 5 sources)" 1 1 || test_fail
+ fi
done
# Sources with large asymmetric delay should be excluded
diff --git a/test/simulation/148-replacement b/test/simulation/148-replacement
index d09fba6e..ee8b2e23 100755
--- a/test/simulation/148-replacement
+++ b/test/simulation/148-replacement
@@ -68,7 +68,7 @@ check_source_selection && test_fail
check_packet_interval || test_fail
check_sync || test_fail
-check_log_messages "Can't synchronise: no majority" 1 1 || test_fail
+check_log_messages "Can't synchronise: no majority (no agreement among 2 sources)" 1 1 || test_fail
check_log_messages "Detected falseticker" 0 2 || test_fail
check_log_messages "Source 192.168.123.. replaced with" 3 60 || test_fail
check_log_messages "Source 192.168.123.1 replaced with" 1 25 || test_fail
commit 2fc7fc2e227f85dcde0953d47e1815432a4a2bf7
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed Mar 12 15:21:18 2025 +0100
sources: delay maxjitter/maxdistance warning messages
Avoid logging the new warning messages about exceeded maxjitter or
maxdistance when only a small number of samples is collected after the
source becomes reachable and the values are unstable. Log the messages
only when a replacement attempt is made.
diff --git a/sources.c b/sources.c
index 3b1766be..c8d96af4 100644
--- a/sources.c
+++ b/sources.c
@@ -769,14 +769,14 @@ mark_source(SRC_Instance inst, SRC_Status status)
if (!inst->reported_status[status]) {
switch (status) {
case SRC_BAD_DISTANCE:
- if (inst->reachability_size < SOURCE_REACH_BITS && inst->bad < BAD_HANDLE_THRESHOLD)
+ if (inst->bad < BAD_HANDLE_THRESHOLD)
break;
log_selection_source(LOGS_WARN, inst,
"Root distance of ## exceeds maxdistance of %.3f seconds",
max_distance);
break;
case SRC_JITTERY:
- if (inst->reachability_size < SOURCE_REACH_BITS && inst->bad < BAD_HANDLE_THRESHOLD)
+ if (inst->bad < BAD_HANDLE_THRESHOLD)
break;
log_selection_source(LOGS_WARN, inst,
"Jitter of ## exceeds maxjitter of %.3f seconds",
commit 0c7e72304aac05020cbaeb4ccab73ce0c441e1ca
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Mar 13 15:40:47 2025 +0100
sources: switch unselect_selected_source() to variable arguments
Switch the function to the full printf style, which will be needed to
log an integer.
diff --git a/sources.c b/sources.c
index c8d96af4..b43ef8dc 100644
--- a/sources.c
+++ b/sources.c
@@ -206,8 +206,7 @@ static LOG_FileID logfileid;
/* Forward prototype */
static void update_sel_options(void);
-static void unselect_selected_source(LOG_Severity severity, const char *format,
- const char *arg);
+static void unselect_selected_source(LOG_Severity severity, const char *format, ...);
static void slew_sources(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything);
static void add_dispersion(double dispersion, void *anything);
@@ -340,7 +339,7 @@ void SRC_DestroyInstance(SRC_Instance instance)
if (selected_source_index > dead_index)
--selected_source_index;
else if (selected_source_index == dead_index)
- unselect_selected_source(LOGS_INFO, NULL, NULL);
+ unselect_selected_source(LOGS_INFO, NULL);
SRC_SelectSource(NULL);
}
@@ -815,16 +814,24 @@ mark_ok_sources(SRC_Status status)
call providing a message or selection of another source, which resets the
report_selection_loss flag. */
+FORMAT_ATTRIBUTE_PRINTF(2, 3)
static void
-unselect_selected_source(LOG_Severity severity, const char *format, const char *arg)
+unselect_selected_source(LOG_Severity severity, const char *format, ...)
{
+ char buf[256];
+ va_list ap;
+
if (selected_source_index != INVALID_SOURCE) {
selected_source_index = INVALID_SOURCE;
report_selection_loss = 1;
}
if (report_selection_loss && format) {
- log_selection_message(severity, format, arg);
+ va_start(ap, format);
+ vsnprintf(buf, sizeof (buf), format, ap);
+ va_end(ap);
+
+ log_selection_message(severity, "%s", buf);
report_selection_loss = 0;
}
}
@@ -947,7 +954,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
}
if (n_sources == 0) {
- unselect_selected_source(LOGS_INFO, "Can't synchronise: no sources", NULL);
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: no sources");
return;
}
@@ -1134,7 +1141,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
if (n_badstats_sources && n_sel_sources && selected_source_index == INVALID_SOURCE &&
max_sel_reach_size < SOURCE_REACH_BITS && max_sel_reach >> 1 == max_badstat_reach) {
mark_ok_sources(SRC_WAITS_STATS);
- unselect_selected_source(LOGS_INFO, NULL, NULL);
+ unselect_selected_source(LOGS_INFO, NULL);
return;
}
@@ -1148,7 +1155,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
if (n_endpoints == 0) {
/* No sources provided valid endpoints */
- unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources", NULL);
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources");
return;
}
@@ -1402,7 +1409,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
/* Before selecting the new synchronisation source wait until the reference
can be updated */
if (sources[max_score_index]->updates == 0) {
- unselect_selected_source(LOGS_INFO, NULL, NULL);
+ unselect_selected_source(LOGS_INFO, NULL);
mark_ok_sources(SRC_WAITS_UPDATE);
return;
}
commit a8094716b0c21a037e3f21d2f3c2e45f14060b07
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Nov 14 13:41:41 2024 +0100
test: add 014-intermittent test
diff --git a/test/simulation/014-intermittent b/test/simulation/014-intermittent
new file mode 100755
index 00000000..2f018ed0
--- /dev/null
+++ b/test/simulation/014-intermittent
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "intermittent connection"
+
+# Pass packets only for 1200 seconds every 10000 seconds
+base_delay=$(cat <<-EOF | tr -d '\n'
+ (+ 1e-4
+ (* -1
+ (equal 0.1 (min (% time 10000) 1200) 1200)))
+EOF
+)
+
+time_max_limit=1e-1
+freq_max_limit=1e-2
+time_rms_limit=2e-3
+freq_rms_limit=2e-5
+limit=100000
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+check_sync || test_fail
+
+check_log_messages "Can't.*no selectable sources" 9 10 || test_fail
+check_log_messages "Selected source 192.168.123.1" 9 10 || test_fail
+
+# Pass every 20th request
+base_delay=$(cat <<-EOF | tr -d '\n'
+ (+ 1e-4
+ (* -1
+ (equal 0.1 from 2)
+ (equal 0.1 (min (% (sum 1) 20) 1) 1)))
+EOF
+)
+
+time_max_limit=1e-2
+freq_max_limit=1e-4
+time_rms_limit=5e-3
+max_sync_time=22000
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+check_sync || test_fail
+
+check_log_messages "Can't.*no selectable sources" 5 15 || test_fail
+check_log_messages "Selected source 192.168.123.1" 5 15 || test_fail
+
+test_pass
commit aa3660256a83768aa3fb640f6032780000c7a4fb
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Mar 13 15:55:32 2025 +0100
sources: improve no-selectable-sources log message
Include the number of unreachable sources in the "Can't synchronise: no
selectable sources" log message to provide a hint whether it might be a
networking issue.
diff --git a/sources.c b/sources.c
index b43ef8dc..406c2f86 100644
--- a/sources.c
+++ b/sources.c
@@ -937,7 +937,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
struct timespec now, ref_time;
int i, j, j1, j2, index, sel_prefer, n_endpoints, n_sel_sources, sel_req_source;
int max_badstat_reach, max_badstat_reach_size, n_badstats_sources;
- int max_sel_reach, max_sel_reach_size;
+ int max_sel_reach, max_sel_reach_size, n_unreach_sources;
int depth, best_depth, trust_depth, best_trust_depth, n_sel_trust_sources;
int combined, stratum, min_stratum, max_score_index;
int orphan_stratum, orphan_source;
@@ -966,6 +966,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
n_endpoints = 0;
n_sel_sources = n_sel_trust_sources = 0;
n_badstats_sources = 0;
+ n_unreach_sources = 0;
sel_req_source = 0;
max_sel_reach = max_badstat_reach = 0;
max_sel_reach_size = max_badstat_reach_size = 0;
@@ -988,6 +989,10 @@ SRC_SelectSource(SRC_Instance updated_inst)
continue;
}
+ /* Count unreachable sources for a warning message */
+ if (sources[i]->reachability == 0)
+ n_unreach_sources++;
+
si = &sources[i]->sel_info;
SST_GetSelectionData(sources[i]->stats, &now,
&si->lo_limit, &si->hi_limit, &si->root_distance,
@@ -1155,7 +1160,8 @@ SRC_SelectSource(SRC_Instance updated_inst)
if (n_endpoints == 0) {
/* No sources provided valid endpoints */
- unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources");
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources"
+ " (%d unreachable sources)", n_unreach_sources);
return;
}
diff --git a/test/simulation/014-intermittent b/test/simulation/014-intermittent
index 2f018ed0..4af574b7 100755
--- a/test/simulation/014-intermittent
+++ b/test/simulation/014-intermittent
@@ -22,7 +22,7 @@ run_test || test_fail
check_chronyd_exit || test_fail
check_sync || test_fail
-check_log_messages "Can't.*no selectable sources" 9 10 || test_fail
+check_log_messages "Can't.*no selectable sources (1 unreachable" 9 10 || test_fail
check_log_messages "Selected source 192.168.123.1" 9 10 || test_fail
# Pass every 20th request
@@ -43,7 +43,7 @@ run_test || test_fail
check_chronyd_exit || test_fail
check_sync || test_fail
-check_log_messages "Can't.*no selectable sources" 5 15 || test_fail
+check_log_messages "Can't.*no selectable sources (1 unreachable" 5 15 || test_fail
check_log_messages "Selected source 192.168.123.1" 5 15 || test_fail
test_pass
commit 402d5d9eb5767797e3af150119b63a08adf43813
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Mar 13 16:03:59 2025 +0100
sources: increase severity of can't-synchronise log messages
Switch the info-level "Can't synchronise" selection messages to
warnings.
diff --git a/sources.c b/sources.c
index 406c2f86..cfe7f260 100644
--- a/sources.c
+++ b/sources.c
@@ -954,7 +954,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
}
if (n_sources == 0) {
- unselect_selected_source(LOGS_INFO, "Can't synchronise: no sources");
+ unselect_selected_source(LOGS_WARN, "Can't synchronise: no sources");
return;
}
@@ -1160,7 +1160,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
if (n_endpoints == 0) {
/* No sources provided valid endpoints */
- unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources"
+ unselect_selected_source(LOGS_WARN, "Can't synchronise: no selectable sources"
" (%d unreachable sources)", n_unreach_sources);
return;
}
@@ -1306,7 +1306,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
}
if (!n_sel_sources || sel_req_source || n_sel_sources < CNF_GetMinSources()) {
- unselect_selected_source(LOGS_INFO, "Can't synchronise: %s selectable sources",
+ unselect_selected_source(LOGS_WARN, "Can't synchronise: %s selectable sources",
!n_sel_sources ? "no" :
sel_req_source ? "no required source in" : "not enough");
mark_ok_sources(SRC_WAITS_SOURCES);

View File

@ -0,0 +1,226 @@
commit b9b338a8df23927d8104f41ecb21baa3558de0cd
Author: Miroslav Lichvar <mlichvar@redhat.com>
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

View File

@ -1,39 +0,0 @@
commit e11b518a1ffa704986fb1f1835c425844ba248ef
Author: Miroslav Lichvar <mlichvar@redhat.com>
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

View File

@ -0,0 +1,279 @@
commit d6aab8da1533b169385c749f8d1320c2b568a149
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Jun 2 10:53:47 2025 +0200
conf: fix sourcedir reloading to not multiply sources
The sourcedir reload triggered by the chronyc "reload sources"
command incorrectly assumed that NSR_AddSourceByName() can return
only the NSR_Success status when a source is added. It ignored the
NSR_UnresolvedName status returned for a source whose name needs to
be resolved after the call (i.e. not specified with an IP address)
and added the source again, effectively multiplying it if the name
can be resolved to a different IP address.
Fix the code to check for the NSR_UnresolvedName status to correctly
determine whether the source was already added before and should not be
added again.
Reported-by: MichaelR <MichaelR42@runbox.com>
Fixes: 916ed70c4a81 ("conf: save source status in sourcedir reload")
diff --git a/conf.c b/conf.c
index cbb11304..59a2e5c9 100644
--- a/conf.c
+++ b/conf.c
@@ -1742,8 +1742,8 @@ reload_source_dirs(void)
NTP_Source *prev_sources, *new_sources, *source;
unsigned int i, j, prev_size, new_size, unresolved;
char buf[MAX_LINE_LENGTH];
+ int d, pass, was_added;
NSR_Status s;
- int d, pass;
/* Ignore reload command before adding configured sources */
if (!conf_ntp_sources_added)
@@ -1782,13 +1782,16 @@ reload_source_dirs(void)
else
d = i < prev_size ? -1 : 1;
+ was_added = d <= 0 && (prev_sources[i].status == NSR_Success ||
+ prev_sources[i].status == NSR_UnresolvedName);
+
/* Remove missing sources before adding others to avoid conflicts */
- if (pass == 0 && d < 0 && prev_sources[i].status == NSR_Success) {
+ if (pass == 0 && d < 0 && was_added) {
NSR_RemoveSourcesById(prev_sources[i].conf_id);
}
/* Add new sources and sources that could not be added before */
- if (pass == 1 && (d > 0 || (d == 0 && prev_sources[i].status != NSR_Success))) {
+ if (pass == 1 && (d > 0 || (d == 0 && !was_added))) {
source = &new_sources[j];
s = NSR_AddSourceByName(source->params.name, source->params.family, source->params.port,
source->pool, source->type, &source->params.params,
commit 778331092436c2f2077a7d0b6253ca1771fb8e27
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Jun 3 10:58:00 2025 +0200
test: add 149-sourcedir test
diff --git a/test/simulation/149-sourcedir b/test/simulation/149-sourcedir
new file mode 100755
index 00000000..77b8499f
--- /dev/null
+++ b/test/simulation/149-sourcedir
@@ -0,0 +1,189 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "sourcedir directive"
+
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
+servers=4
+limit=191
+update_executable="tmp/update-sourcedir"
+client_server_conf="sourcedir tmp"
+base_delay="(+ 1e-4 (* 5 (equal 0.1 from $[servers + 2])))"
+chronyc_start=1
+chronyc_conf="timeout 6000
+activity
+$(for i in $(seq 1 18); do echo "reload sources"; echo activity; done)"
+
+cat > tmp/sources.sources <<EOF
+pool nodes-1-2-3-4.net1.clk iburst
+EOF
+
+cat > tmp/update-sourcedir <<EOF
+#!/usr/bin/env bash
+case "\$1" in
+ 19) s="pool nodes-1-2-3-4.net1.clk";;
+ 39) s="pool nodes-1-2-3-4.net1.clk maxsources 3";;
+ 59) s="pool nodes-1-2-3.net1.clk";;
+ 79) s="pool nodes-1-2-3.net1.clk
+ server nodes-3-4.net1.clk";;
+ 99) s="server nodes-3-4.net1.clk";;
+ 119) s="server nodes-1-2-3.net1.clk";;
+ 139) s="server 192.168.123.2";;
+ 159) s="server 192.168.123.2 maxdelay 0.1";;
+ 179) s="";;
+ *) exit 0;;
+esac
+echo "\$s" > tmp/sources.sources
+EOF
+chmod 755 tmp/update-sourcedir
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+
+check_log_messages "T00:0.:[135].Z \(Added\|Removed\)" 0 0 || test_fail
+check_log_messages "T00:0.:..Z Added pool nodes-1-2-3-4\." 3 3 || test_fail
+check_log_messages "T00:0.:..Z Removed pool nodes-1-2-3-4\." 3 3 || test_fail
+check_log_messages "T00:0.:..Z Added pool nodes-1-2-3\." 1 1 || test_fail
+check_log_messages "T00:0.:..Z Removed pool nodes-1-2-3\." 1 1 || test_fail
+check_log_messages "T00:0.:..Z Added source ID#" 2 2 || test_fail
+check_log_messages "T00:0.:..Z Added source 192.168.123.[1234]" 2 2 || test_fail
+check_log_messages "T00:0.:..Z Removed source 192.168.123.[1234]" 4 4 || test_fail
+
+check_chronyc_output "^200 OK
+0 sources online
+0 sources offline
+4 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+4 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+4 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+4 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+3 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+3 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+3 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+5 sources with unknown address
+200 OK
+200 OK
+3 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+5 sources with unknown address
+200 OK
+200 OK
+4 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+5 sources with unknown address
+200 OK
+200 OK
+4 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+5 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+1 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address
+200 OK
+200 OK
+0 sources online
+0 sources offline
+0 sources doing burst \(return to online\)
+0 sources doing burst \(return to offline\)
+0 sources with unknown address$" || test_fail
+
+check_packet_interval || test_fail
+
+test_pass
diff --git a/test/simulation/test.common b/test/simulation/test.common
index 42a2917b..7eb348e3 100644
--- a/test/simulation/test.common
+++ b/test/simulation/test.common
@@ -39,6 +39,7 @@ default_refclock_jitter=""
default_refclock_offset=0.0
default_update_interval=0
+default_update_executable=""
default_shift_pll=2
default_server_strata=1
@@ -442,7 +443,9 @@ run_simulation() {
-o tmp/log.offset -f tmp/log.freq -p tmp/log.packets \
-R $(awk "BEGIN {print $update_interval < 0 ? 2^-($update_interval) : 1}") \
-r $(awk "BEGIN {print $max_sync_time * 2^$update_interval}") \
- -l $(awk "BEGIN {print $limit * 2^$update_interval}") && test_ok || test_error
+ -l $(awk "BEGIN {print $limit * 2^$update_interval}") \
+ $([ "$update_executable" != "" ] && printf "%s" "-e $update_executable") && \
+ test_ok || test_error
}
run_test() {

View File

@ -0,0 +1,64 @@
commit 1205197f2e15166a47fa1817feaf3587738fb37a
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed Nov 27 16:03:19 2024 +0100
avoid timestamps from future in PTP_SYS_OFFSET_EXTENDED
diff --git a/client.c b/client.c
index 065eddf..32796e0 100644
--- a/client.c
+++ b/client.c
@@ -2065,24 +2065,24 @@ int ioctl(int fd, unsigned long request, ...) {
} else if (request == PTP_SYS_OFFSET_EXTENDED && fd == REFCLK_FD) {
struct ptp_sys_offset_extended *sys_off = va_arg(ap, struct ptp_sys_offset_extended *);
struct timespec ts, ts1, ts2;
+ double delay;
int i;
if (sys_off->n_samples > PTP_MAX_SAMPLES)
sys_off->n_samples = PTP_MAX_SAMPLES;
for (i = 0; i < sys_off->n_samples; i++) {
+ clock_gettime(CLOCK_REALTIME, &ts2);
clock_gettime(REFCLK_ID, &ts);
- sys_off->ts[i][1].sec = ts.tv_sec;
- sys_off->ts[i][1].nsec = ts.tv_nsec;
- }
-
- clock_gettime(CLOCK_REALTIME, &ts);
- for (i = 0; i < sys_off->n_samples; i++) {
- ts1 = ts, ts2 = ts;
- add_to_timespec(&ts1, -get_phc_delay(-1));
- add_to_timespec(&ts2, get_phc_delay(1));
+ delay = get_phc_delay(1);
+ add_to_timespec(&ts, -delay);
+ delay += get_phc_delay(-1);
+ ts1 = ts2;
+ add_to_timespec(&ts1, -delay);
sys_off->ts[i][0].sec = ts1.tv_sec;
sys_off->ts[i][0].nsec = ts1.tv_nsec;
+ sys_off->ts[i][1].sec = ts.tv_sec;
+ sys_off->ts[i][1].nsec = ts.tv_nsec;
sys_off->ts[i][2].sec = ts2.tv_sec;
sys_off->ts[i][2].nsec = ts2.tv_nsec;
}
commit 8b8831d98df1fca21288a9bc18c6a8fbfe6874a6
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed Nov 27 16:06:40 2024 +0100
round nanoseconds in PTP_SYS_OFFSET* delay adjustments
diff --git a/client.c b/client.c
index 32796e0..0e235a6 100644
--- a/client.c
+++ b/client.c
@@ -794,7 +794,7 @@ static void normalize_timespec(struct timespec *tp) {
static void add_to_timespec(struct timespec *tp, double offset) {
tp->tv_sec += floor(offset);
- tp->tv_nsec += (offset - floor(offset)) * 1e9;
+ tp->tv_nsec += round((offset - floor(offset)) * 1e9);
normalize_timespec(tp);
}

View File

@ -1,5 +1,5 @@
%global _hardened_build 1
%global clknetsim_ver 5d1dc0
%global clknetsim_ver cdd694
%bcond_without debug
%bcond_without nts
@ -8,8 +8,8 @@
%endif
Name: chrony
Version: 4.5
Release: 1%{?dist}
Version: 4.6.1
Release: 2%{?dist}
Summary: An NTP client/server
License: GPLv2
@ -29,8 +29,19 @@ 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
# 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
# improve description of refresh directive
Patch6: chrony-docrefresh.patch
# improve logging of selection failures
Patch7: chrony-logselect.patch
# fix sourcedir reloading to not multiply sources
Patch8: chrony-sourcedir.patch
# revert clknetsim changes in PHC breaking old refclock tests
Patch20: clknetsim-revert-phc.patch
BuildRequires: gnutls-devel libcap-devel libedit-devel pps-tools-devel
BuildRequires: gcc gcc-c++ make bison systemd gnupg2
@ -61,10 +72,18 @@ service to other computers in the network.
%{gpgverify} --keyring=%{SOURCE2} --signature=%{SOURCE1} --data=%{SOURCE0}
%setup -q -n %{name}-%{version}%{?prerelease} -a 10
%{?gitpatch:%patch0 -p1}
%patch1 -p1 -b .nm-dispatcher-dhcp
%patch2 -p1 -b .keys
%patch3 -p1 -b .services
%patch4 -p1 -b .serverstats
%patch -P 1 -p1 -b .nm-dispatcher-dhcp
%patch -P 2 -p1 -b .keys
%patch -P 3 -p1 -b .services
%patch -P 4 -p1 -b .defconfig
%patch -P 5 -p1
%patch -P 6 -p1 -b .docrefresh
%patch -P 7 -p1
%patch -P 8 -p1
pushd clknetsim-*-%{clknetsim_ver}*
%patch -P 20 -R -p1
popd
%{?gitpatch: echo %{version}-%{gitpatch} > version.txt}
@ -217,6 +236,27 @@ fi
%dir %attr(750,chrony,chrony) %{_localstatedir}/log/chrony
%changelog
* Wed Jun 04 2025 Miroslav Lichvar <mlichvar@redhat.com> 4.6.1-2
- improve description of refresh directive (RHEL-82096)
- improve logging of selection failures (RHEL-80388 RHEL-80413 RHEL-80415)
- fix sourcedir reloading to not multiply sources (RHEL-95016)
- switch from patchX to patch -P X
* Wed Nov 06 2024 Miroslav Lichvar <mlichvar@redhat.com> 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 <mlichvar@redhat.com> 4.6-1
- update to 4.6 (RHEL-56964)
* Thu Aug 08 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.5-3
- don't repeat error log messages when reloading sourcedir (RHEL-51786)
- add support for leap-seconds.list file (RHEL-53484)
* Thu Jun 13 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.5-2
- fix crash on reload command during start (RHEL-28945)
* Tue Jan 09 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.5-1
- update to 4.5 (RHEL-6522 RHEL-6520 RHEL-9969 RHEL-9971 RHEL-9973 RHEL-9975
RHEL-12411)