update to 4.8 (RHEL-112593)
Resolves: RHEL-112593
This commit is contained in:
parent
dce1cabbe2
commit
bdf64a3574
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
17
chrony-defconfig.patch
Normal 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.
|
||||
@ -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.
|
||||
@ -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);
|
||||
@ -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
|
||||
@ -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
23
chrony-tests.patch
Normal 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
|
||||
32
chrony.spec
32
chrony.spec
@ -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 \
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
6
sources
6
sources
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user