From 26d528a642433031e14580cad0db841b6f60897d Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 19 Jan 2019 04:25:44 -0600 Subject: [PATCH 14/15] use adjtimex over adjtime, check return value and adjust offset as needed --- src/usr.sbin/ntpd/ntpd.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/usr.sbin/ntpd/ntpd.c b/src/usr.sbin/ntpd/ntpd.c index c3b7ab07e1..8d4bffa3e3 100644 --- a/src/usr.sbin/ntpd/ntpd.c +++ b/src/usr.sbin/ntpd/ntpd.c @@ -17,6 +17,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_ADJTIMEX +#include +#endif #include #include #include @@ -478,21 +481,44 @@ reset_adjtime(void) int ntpd_adjtime(double d) { - struct timeval tv, olddelta; int synced = 0; static int firstadj = 1; + double threshold = (double)LOG_NEGLIGIBLE_ADJTIME / 1000; d += getoffset(); - if (d >= (double)LOG_NEGLIGIBLE_ADJTIME / 1000 || - d <= -1 * (double)LOG_NEGLIGIBLE_ADJTIME / 1000) + if (d >= threshold || d <= -1 * threshold) log_info("adjusting local clock by %fs", d); else log_debug("adjusting local clock by %fs", d); + +#ifdef HAVE_ADJTIMEX + int rc; + + long offset = d * 1000000; + struct timex tx = { 0 }; + tx.offset = offset; + tx.modes = ADJ_OFFSET_SINGLESHOT | ADJ_STATUS; + + do { + rc = adjtimex(&tx); + } while (rc == TIME_ERROR && (tx.offset /= 2) > threshold); + + if (rc == TIME_ERROR) { + if ((tx.status & ~STA_UNSYNC)) + log_warn("adjtimex returned TIME_ERROR"); + } else if (rc < 0) { + log_warn("adjtimex failed"); + } else if (!firstadj && tx.offset == offset) { + synced = 1; + } +#else + struct timeval tv, olddelta; d_to_tv(d, &tv); if (adjtime(&tv, &olddelta) == -1) log_warn("adjtime failed"); else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0) synced = 1; +#endif firstadj = 0; update_time_sync_status(synced); return (synced); -- 2.21.0