update to 4.8 (RHEL-112593)

Resolves: RHEL-112593
This commit is contained in:
Miroslav Lichvar 2025-09-11 15:06:16 +02:00
parent dce1cabbe2
commit bdf64a3574
10 changed files with 56 additions and 1264 deletions

6
.gitignore vendored
View File

@ -1,3 +1,3 @@
/chrony-4.6.1.tar.gz
/chrony-4.6.1-tar-gz-asc.txt
/clknetsim-cdd694.tar.gz
/chrony-4.8.tar.gz
/chrony-4.8-tar-gz-asc.txt
/clknetsim-6ee99f50dec8.tar.gz

17
chrony-defconfig.patch Normal file
View File

@ -0,0 +1,17 @@
diff --git a/examples/chrony.conf.example2 b/examples/chrony.conf.example2
index a257f54c..03e7d47b 100644
--- a/examples/chrony.conf.example2
+++ b/examples/chrony.conf.example2
@@ -1,10 +1,5 @@
-# Note: The general recommendation for an NTP client is to have at least
-# three NTP servers to be able to detect one server providing incorrect
-# time (falseticker).
-
-# Use four public NTP servers from the pool.ntp.org project. If this
-# host has a static public IP address, please consider joining the pool:
-# https://www.ntppool.org/join.html
+# Use public servers from the pool.ntp.org project.
+# Please consider joining the pool (https://www.pool.ntp.org/join.html).
pool pool.ntp.org iburst
# Record the rate at which the system clock gains/losses time.

View File

@ -1,55 +0,0 @@
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

@ -1,612 +0,0 @@
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

@ -1,226 +0,0 @@
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,279 +0,0 @@
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() {

23
chrony-tests.patch Normal file
View File

@ -0,0 +1,23 @@
commit a0f460569eae04ee491585b7a9cc7dc2eec44d64
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Oct 27 15:57:05 2025 +0100
test: make 007-cmdmon test even more reliable
The last hit value in the clients report may be "-", because there is
a backward step of the clock caused by the doffset and reset sources
commands.
diff --git a/test/system/007-cmdmon b/test/system/007-cmdmon
index 4660ffad..3fd88fa3 100755
--- a/test/system/007-cmdmon
+++ b/test/system/007-cmdmon
@@ -68,7 +68,7 @@ check_chronyc_output "^Name/IP address Mode KeyID Type KLen Last Atm
run_chronyc "clients" || test_fail
check_chronyc_output "^Hostname NTP Drop Int IntL Last Cmd Drop Int Last
===============================================================================
-.*127\.0\.0\.1 [0-9 ]+ 0 [-0-9 ]+ - [ 0-9]+ 0 0 - -.*$" \
+.*127\.0\.0\.1 [0-9 ]+ 0 [-0-9 ]+ - [-0-9 ]+ 0 0 - -.*$" \
|| test_fail
run_chronyc "ntpdata $server" || test_fail

View File

@ -1,5 +1,5 @@
%global _hardened_build 1
%global clknetsim_ver cdd694
%global clknetsim_ver 6ee99f50dec8
%bcond_without debug
%bcond_without nts
@ -8,7 +8,7 @@
%endif
Name: chrony
Version: 4.6.1
Version: 4.8
Release: 2%{?dist}
Summary: An NTP client/server
@ -25,17 +25,10 @@ Source10: https://gitlab.com/chrony/clknetsim/-/archive/master/clknetsim-%
# add distribution-specific bits to DHCP dispatcher
Patch1: chrony-nm-dispatcher-dhcp.patch
# keep PHC refclock reachable when dropping samples due to high delay
Patch2: chrony-refclkreach.patch
# improve description of refresh directive
Patch3: chrony-docrefresh.patch
# improve logging of selection failures
Patch4: chrony-logselect.patch
# fix sourcedir reloading to not multiply sources
Patch5: chrony-sourcedir.patch
# revert clknetsim changes in PHC breaking old refclock tests
Patch20: clknetsim-revert-phc.patch
# revert upstream changes in packaged configuration examples
Patch4: chrony-defconfig.patch
# make tests more reliable
Patch5: chrony-tests.patch
BuildRequires: gnutls-devel libcap-devel libedit-devel pps-tools-devel
BuildRequires: gcc gcc-c++ make bison systemd gnupg2
@ -70,15 +63,9 @@ service to other computers in the network.
%setup -q -n %{name}-%{version}%{?prerelease} -a 10
%{?gitpatch:%patch -P 0 -p1}
%patch -P 1 -p1 -b .nm-dispatcher-dhcp
%patch -P 2 -p1
%patch -P 3 -p1 -b .docrefresh
%patch -P 4 -p1
%patch -P 4 -p1 -b .defconfig
%patch -P 5 -p1
pushd clknetsim-*-%{clknetsim_ver}*
%patch -P 20 -R -p1
popd
%{?gitpatch: echo %{version}-%{gitpatch} > version.txt}
# review changes in packaged configuration files and scripts
@ -88,8 +75,8 @@ md5sum -c <<-EOF | (! grep -v 'OK$')
6a3178c4670de7de393d9365e2793740 examples/chrony.logrotate
c3992e2f985550739cd1cd95f98c9548 examples/chrony.nm-dispatcher.dhcp
4e85d36595727318535af3387411070c examples/chrony.nm-dispatcher.onoffline
c11159b78b89684eca773db6236a9855 examples/chronyd.service
46fa3e2d42c8eb9c42e71095686c90ed examples/chronyd-restricted.service
274a44cd51981d6d4d3a44dfc92c94ab examples/chronyd.service
5ddbb8a8055f587cb6b0b462ca73ea46 examples/chronyd-restricted.service
EOF
# don't allow packaging without vendor zone
@ -124,6 +111,7 @@ mv clknetsim-*-%{clknetsim_ver}* test/simulation/clknetsim
--chronyrundir=/run/chrony \
--docdir=%{_docdir} \
--with-ntp-era=$(date -d '1970-01-01 00:00:00+00:00' +'%s') \
--with-chronyc-user=root \
--with-user=chrony \
--with-hwclockfile=%{_sysconfdir}/adjtime \
--with-pidfile=/run/chrony/chronyd.pid \

View File

@ -1,64 +0,0 @@
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,3 +1,3 @@
SHA512 (chrony-4.6.1.tar.gz) = 646ae08f2587366236796f2399d8ab3eb570979e0d82f5d13f5cec49939054c876cc93dc20c8d38e105fd3500e1720d05a223a15076783cd882d0de43afd9c7e
SHA512 (chrony-4.6.1-tar-gz-asc.txt) = 992b706636bf3a7eb6d502562a4990c9d8e20e5f3011d2cdb2ceb32220e9a1c2bfa6eca767212cee49b811823872602dc33f9e7201a7f9a93cc9c90e81b1db49
SHA512 (clknetsim-cdd694.tar.gz) = 289641461bd8c7227547478ba8cd51b7a114da3e34c994fe652382b0fb4df386c8734585bbcfa3ee5b99891cc6eef305997c5a7d92ea06b2cc6e94480aea5e75
SHA512 (chrony-4.8.tar.gz) = 949b796bb34db32a5c1b9e6b53be6a22e51c59f24a316d585b8a52a52ab1f61bdf0378dc58b282bb0ba4fac1f05e1e99fbe37cb4259aa2b359e7bf679c176aab
SHA512 (chrony-4.8-tar-gz-asc.txt) = df7f4e06f74a4b8c9a49e8fe57ea02e0324c5683d036412c32192a09f08e08f33537609cef8df0b4302bfcd63332b3092f33f40c8d02857c93ecea13822b5b47
SHA512 (clknetsim-6ee99f50dec8.tar.gz) = 2621d1c44b84b42fcdf644f236ff90dab9f8a8407a138c8719c53dd9c4f21480db3b4ba598116aa1b9d6bd1fa02fc410d85a43baf55ddf8ad47fc09aba4c4477