How do I check whether my system's clock is synchronized to a NTP server?
Asked Answered
O

1

1

I have an application on a Linux system (Ubuntu Server) that needs to know whether the current system clock has been synchronized to a NTP server. While I could check timedatectl's output for System clock synchronized: yes, this seems very brittle, especially since timedatectl's human readable output might change in the future.

However, systemd seems to be full of DBus interfaces, so I suspect that there might be a way to check there. Either way, I'm looking for a bool is_ntp_synchronized().

Is there any way to simply check whether the system clock is synchronized without starting another process?

Ornelas answered 17/12, 2020 at 13:52 Comment(1)
Note: you want to know if NTP synchronized the time, or if computer synchronized time to a server? [for the first: you may use hardware (e.g. GPS clock) attached to NTP daemon. for the second, in past we had ntpdate, called regularly, but not ntp daemon running].Locris
O
2

Linux provides adjtimex, which also gets used by systemd. You can check various fields to determine if you're still synchronized. A non-negative return value unequal to TIME_ERROR might be your forte, although you might use the maxerror or other fields to check the clock's quality instead.

#include <stdio.h>
#include <sys/timex.h>

int main()
{
    struct timex timex_info = {};
    timex_info.modes = 0;         /* explicitly don't adjust any time parameters */

    int ntp_result = ntp_adjtime(&timex_info);

    printf("Max       error: %9ld (us)\n", timex_info.maxerror);
    printf("Estimated error: %9ld (us)\n", timex_info.esterror);
    printf("Clock precision: %9ld (us)\n", timex_info.precision);
    printf("Jitter:          %9ld (%s)\n", timex_info.jitter,
           (timex_info.status & STA_NANO) ? "ns" : "us");
    printf("Synchronized:    %9s\n", 
           (ntp_result >= 0 && ntp_result != TIME_ERROR) ? "yes" : "no");
    return 0;
}

Note that systemd explicitly ignores the reported result (except for errors) and instead checks that the timex_info.maxerror value hasn't become more than 16 seconds.

This interface has also been provided since the pre-git times. As such, it's guaranteed to be stable, as it might otherwise break Linux's don't-break-userspace-policy.

Ornelas answered 17/12, 2020 at 13:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.