diff --git a/.gitignore b/.gitignore index 720db73..2d9020d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /chrony-4.6.1.tar.gz /chrony-4.6.1-tar-gz-asc.txt -/clknetsim-40bb97.tar.gz +/clknetsim-cdd694.tar.gz diff --git a/chrony-sourcedir.patch b/chrony-sourcedir.patch new file mode 100644 index 0000000..8ccd708 --- /dev/null +++ b/chrony-sourcedir.patch @@ -0,0 +1,279 @@ +commit d6aab8da1533b169385c749f8d1320c2b568a149 +Author: Miroslav Lichvar +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 + 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 +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 < tmp/update-sourcedir < 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() { diff --git a/chrony.spec b/chrony.spec index 5b1354a..a9e680d 100644 --- a/chrony.spec +++ b/chrony.spec @@ -1,5 +1,5 @@ %global _hardened_build 1 -%global clknetsim_ver 40bb97 +%global clknetsim_ver cdd694 %bcond_without debug %bcond_without nts @@ -37,6 +37,11 @@ Patch5: chrony-refclkreach.patch Patch6: chrony-docrefresh.patch # improve logging of selection failures Patch7: chrony-logselect.patch +# fix sourcedir reloading to not multiply sources +Patch8: chrony-sourcedir.patch + +# revert clknetsim changes in PHC breaking old refclock tests +Patch20: clknetsim-revert-phc.patch BuildRequires: gnutls-devel libcap-devel libedit-devel pps-tools-devel BuildRequires: gcc gcc-c++ make bison systemd gnupg2 @@ -74,6 +79,11 @@ service to other computers in the network. %patch5 -p1 %patch6 -p1 -b .docrefresh %patch7 -p1 +%patch8 -p1 + +pushd clknetsim-*-%{clknetsim_ver}* +%patch20 -R -p1 +popd %{?gitpatch: echo %{version}-%{gitpatch} > version.txt} diff --git a/clknetsim-revert-phc.patch b/clknetsim-revert-phc.patch new file mode 100644 index 0000000..65c2ae3 --- /dev/null +++ b/clknetsim-revert-phc.patch @@ -0,0 +1,64 @@ +commit 1205197f2e15166a47fa1817feaf3587738fb37a +Author: Miroslav Lichvar +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 +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); + } + diff --git a/sources b/sources index f2f30be..3e29292 100644 --- a/sources +++ b/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-40bb97.tar.gz) = d0085340a7219dedbe1298f0c709824bcf6f698207cd1be87de38d108b829cd771ac0ea720ee83de3810c4530664a22e122f513516f1174bb9139eddbd359590 +SHA512 (clknetsim-cdd694.tar.gz) = 289641461bd8c7227547478ba8cd51b7a114da3e34c994fe652382b0fb4df386c8734585bbcfa3ee5b99891cc6eef305997c5a7d92ea06b2cc6e94480aea5e75