timedatectl does not correctly show the actual status of NTP as synchronized

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux (RHEL)
  • ntp
  • chrony

Issue

  • Although ntpstat shows the status as synchronised to NTP server (10.0.0.1) at stratum 3, timedatectl still shows NTP synchronized: no
  • ntpq -p for ntpd and chronyc sources for chronyd, show an "*" indicating that the client is synchronizing correctly.

Resolution

Workaround

  • For ntpd: run the ntpddeamon without the option -x

    1. Edit the ntpd configuration file and remove the -x option

       # vi /etc/sysconfig/ntpd
      
    2. Restart the ntpd.service

       # systemctl restart ntpd.service
      
  • For chronyd: add the option rtcsync in /etc/chrony.conf if it is not there (it is included in the default configuration).

Root Cause

The kernel maintains an "unsynchronized" flag for the system clock. The timedatectl program will print "NTP synchronized: yes" only if this flag is cleared (set to zero). It doesn't support the protocol which ntpstat uses to query the state of ntpd.

ntpd can control the system clock using two different system functions:
- ntp_adjtime() enables a phase-locked loop implemented in the kernel (aka kernel discipline), which automatically corrects the frequency offset of the clock (drift) and it needs to be called only when a new measurement is made. It clears the "unsynchronized" flag in the kernel. The main limitation is that it cannot correct offsets larger than 0.5 seconds.
- adjtime() is an older method, which makes a one-time adjustment of the clock (slew). It doesn't correct the frequency offset, so it needs to be called frequently to compensate for it, even when no measurement is made. It cannot clear the "unsynchronized" flag in the kernel, but it can correct any offset.

ntpd can use ntp_adjtime() or adjtime(), but not both at the same time. By default it uses ntp_adjtime(). If the step threshold is set to a larger value than 0.5 seconds (e.g. by enabling the -x option), it has to switch to adjtime(), because ntp_adjtime() does not work with larger offsets.

That means the kernel "unsynchronized" status will not be cleared and timedatectl will report "NTP synchronized: no" when ntpd is started with the -x option.

Diagnostic Steps

  • How to verify that timedatectl does not show correct status:

    # timedatectl | grep NTP
    NTP enabled: yes
    NTP synchronized: no
    
    # ntpstat
    synchronised to NTP server (10.0.0.1) at stratum 3
    time correct to within 1026 ms
    

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments