Distributing local time
Most of the time, TimeKeeper receives and/or distributes from an authoritative upstream source. That source may be NTP from a server or a direct connection to GPS or PTP from a grandmaster or a PPS, or a number of other sources. No matter what the source is, TimeKeeper tracks it and may serve time based on it.
In some cases though, there may be no external connectivity at all, and all that’s present is the local system itself for time. TimeKeeper can take the local clock and use it as the ‘source’ of time, and use that as a source to steer any time served to clients.
This is common with clusters of systems that need to be tightly synchronized to each other, but that synchronization may not need to match any outside time reference like GPS.
Configuring TimeKeeper to distribute local time
TimeKeeper calls this type of source self and it’s configured with the PPSDEV parameter. With a primary source declared as PPSDEV=self, TimeKeeper will serve the local system time in any configured PTP servers, and will also respond with that time when queried via NTP.
The configuration for this type of source looks like the following, with the ability to serve that time via NTP to any clients:
SOURCE0() { PPSDEV=self; }
SERVENTP=1
Any clients that query a system with this configuration will get that system’s time in the NTP response, and steer their clock to match. This approach does have limitations, but it can keep a set of independent machines very tightly synchronized.
WARNING This should not be used, even as a failover source, if clients require accurate time. As a failover source, it’s no better than simply letting TimeKeeper lose all valid time sources, and it generates less severe and infrequent log entries.
For example, the following two configurations behave the same, timing wise. The first generates a single time-source-change alert when TimeKeeper fails over and another when it fails back. The second generates an unable-to-find-valid-time-source alert every three minutes until TimeKeeper fails back whereupon it generates a now-using-source-N alert. The more innocuous alerts generated by the first configuration may be more likely to be ignored or missed.
SOURCE0() { NTPSERVER=hostname; }
SOURCE1() { PPSDEV=self; }
SOURCE0() { NTPSERVER=hostname; }
Something else to consider is that there is no point in configuring sources of a lower priority than a PPSDEV=self source as below. That’s because a PPSDEV=self source cannot fail, so TimeKeeper will never fail over to those lower-priority sources.
SOURCE0() { NTPSERVER=hostname1; }
SOURCE1() { PPSDEV=self; }
SOURCE2() { NTPSERVER=hostname2; }