Linux Clock Guide

Introduction

This note explains how to maintain an accurate clock when running Linux. The instructions are primarily based on using Debian 5.0 (Lenny), but the basics should apply to any Linux distro.

There are two clocks used by Linux. A hardware (or CMOS) clock and a system (or software) clock. When Linux is running the system clock is used to maintain time.

The system clock is extremely reliable and will drift by a precise amount. The drift can be adjusted by altering two values in the Linux Kernel, tick and frequency. Once these values are correct, the system clock will be extremely accurate.

The hardware clock is used to maintain the time whilst the system is not running, i.e. powered down, suspended or hibernated. The system time is set from the hardware clock on startup, and the hardware clock is set to the system time on shutdown.

The hardware clock also drifts by a predictable amount. Once the system clock has been adjusted to maintain good time, the drift of the hardware clock can be predicted and adjusted when the system starts, immediately before setting the system clock, thereby starting the system with a reasonably accurate time. However, this system relies on no other program other than hwclock adjusting the hardware clock and this is often wrong. E.g. Windows uses, and may alter the hardware clock. For this reason, adjusting the hardware clock to account for drift is disabled by default in Debian.

There are three methods to maintain the clocks, depending on how reliably you can access an NTP server.

  1. Use the NTP daemon from the ntp package if you have constant access to one or more NTP servers
  2. Use the chrony daemon from the chrony package if you have intermittent or no access to an NTP server
  3. Use the manual method if you have no, or very poor access to an NTP server and have the patience to fine tune settings

Each of these methods are described in the following sections.

ntpd

Install and configure the ntp package.

For more accurate time servers, change the server settings in /etc/ntp.conf to a server located more geographically close to your system, e.g. for the UK change the server names to 0.uk.pool.ntp.org etc. See http://www.pool.ntp.org/en/use.html for information regarding other geographical regions.

chrony

This is an excellent utility for maintaining the system time when you have infrequent or no access to an NTP server. On Debian systems it can be installed with the chrony package. This completely avoids the need to use the hwclock and adjtimex commands.

The source is available at http://chrony.sunsite.dk/

To maintain the time manually, define the manual option in /etc/chrony/chrony.conf. To enter the correct time, run chronyc as a normal user from the command line. You will need the password that is stored as the value corresponding to the 'commandkey' in the main configuration file. The passwords are specified in /etc/chrony/chrony.keys.

Start chronyc from the command line as a normal user.

    $ chronyc
    chronyc> password SECRET
    chronyc> manual on
    chronyc> settime hh:mm:ss
    chronyc> quit

To remove incorrectly entered manual times:

    chronyc> manual list
    chronyc> manual delete XXX

info chronyc provides thorough documentation.

Otherwise, the default configuration should be fine for automatic use with NTP servers. You may want to change the server configurations in /etc/chrony/chrony.conf to be more geographically close to you, similarly to that described in the ntp section above.

If you have a system where the system clock is frequently not running, you may wish to run the manual method (described below) for a while to fine tune the default settings, for both the hardware and software clocks. In that way, when the system is started and chrony has no access to an NTP server, the time will be more accurate.

You may need to restart the chrony daemon after obtaining an Internet connection. You can check it's working OK by issuing the following command:

    $ chronyc sources

If chrony has successfully connected to NTP servers they will be listed, otherwise the list may be empty.

To restart the chrony daemon:

    # /etc/init.d/chrony restart

To see the current status:

    $ chronyc tracking

manual

This method can be used to fine tune the drift settings for both the hardware and software clocks over a long period of time. Eventually you can determine very accurate settings, providing reasonably accurate clocks requiring infrequent adjustment. However, it does require some effort to build up the statistical data to provide accurate settings.

Install the adjtimex package. Remove the ntp and chronyc packages. If you are using the manual method to provide good default values when you do not have access to NTP, you can reinstall one of these packages after obtaining satisfactory defaults.

If you wish to reset any previous values that may exist for the drift settings, delete the following files:

  • /etc/adjtime
  • /etc/default/adjtimex
  • /var/log/clocks

The adjtimex program is used to build statistics over time in /var/log/clocks which will provide values to set for adjustments to the hardware clock's drift rate in /etc/adjtime and the software clock's drift rate in /etc/default/adjtimex.

hwclock will adjust values in /etc/adjtime, but these may not be as reliable as those recommended by adjtimex.

Implement the following procedures to fine tune the values over time:

  1. Read /usr/share/doc/util-linux/README.Debian.hwclock

  2. Optionally, modify /etc/init.d/hwclock.sh and /etc/init.d/hwclockfirst.sh to call /sbin/hwclock --adjust by uncommenting the command to enable it. (If the server is only going to be down for very short periods whilst being rebooted, it's probably not worth worrying about the drift settings for hwclock.)

  3. From time-to-time, set the software clock using adjtimex (see below), especially just after startup and just before shutdown, to maximise collection of statistics

  4. Before shutdown, if you have enabled hwclock --adjust on startup, and you're going to use another operating system, (e.g. Windows), which may modify the hardware clock, delete /etc/adjtime so that hwclock --adjust is ineffective on restarting Linux.

Checking and setting the time with adjtimex

You can update the statistics being gathered by adjtimex by running adjtimex using the --watch or --host switches. If you have access to one or more NTP servers, use the --host switch (which also implies the --watch switch) to check the system clock's time. Otherwise, just use the --watch switch and an accurate clock.

Using NTP servers

    # adjtimex --host 0.pool.ntp.org 1.pool.ntp.org

Manual

Use an accurate source, e.g. GPS or time signal. (For consistency, always use the same source thereafter.)

  1. Enter the following command:

    # adjtimex --watch
    
  2. Press the enter key when you know the time of day.

  3. Check the system time that adjtimex displays. If it's correct, just press enter again to use that time. Otherwise, enter the correct time. Adjtimex displays the time difference.

  4. Either enter the possible amount of error for the time provided, or 'r' to retry or 'q' to quit.

  5. Answer the questions relating to whether the system clock or hardware clocks may have been adjusted. The default values are often correct. If you have any doubt, answer 'n', in which case, no new statistics will be gathered of that type, but they will be the next time you can safely answer 'y'.

This just updates the statistics, it does not alter the hardware or system clocks.

Correcting the system clock

Small corrections (perhaps +/- 0.5 secs) can be made by slewing the system clock with adjtimex --singleshot. This adjusts the clock by usec (millionths of a second). This is by far the best way to make small adjustments.

E.g. If the difference reported when using adjtimex --watch is reported as -0.123, correct the system clock with the following command:

    # adjtimex --singleshot '-123000'

Unfortunately, it's not possible to see whether this is effective or not. It's not clear how this is implemented, but the effect of a half second adjustment seems complete within an hour. The adjtimex documentation states that the rate is changed by about 1 part in 2,000, so by my calculations it should take 1,000 seconds, (just under 17 minutes), to slew half-a second.

Running the adjtimex --print command doesn't show any change in tick or frequency, so I don't know of anyway of confirming the clock has settled back to the specified tick and frequency, other than trial and error using adjtimex --watch to see if the requested slew appears to have been completed, by virtue of the time being correct, then quitting before the values are saved.

It's also not clear whether this impacts the kernel time variables. I'd have thought it does, but the next occasion that adjtimex --watch is run, adjtimex doesn't recognise that as having occurred. Therefore, I think it best to leave it at least an hour after a half-second adjustment, perform another adjtimex --watch and answer 'n' to the question relating to the kernel time variables having been altered.

It's also not clear what the maximum values for --singleshot are. The --offset command takes a usec parameter within the range -512000...512000. I have used 2,000,000 usecs successfully with --singleshot. On that occasion it took about 100 minutes to apply the change.

Alternatively the time and date can be corrected using the standard date command. Other methods are described in /usr/share/doc/util-linux/README.Debian.hwclock, but slewing the clock is the best method where the values are small.

Because of the inaccuracies introduced when using --watch with a manually entered time, it's best to leave long periods of time between updates to /var/log/clocks to avoid accumulating these errors. If you just wish to see the latest values, it's probably best to update a copy of /var/log/clocks instead. e.g.

    # cp /var/log/clocks.log /tmp/
    # adjtimex --log=/tmp/clocks.log --watch
    # adjtimex --review

You only need to update the default clocks.log file before doing anything that would alter either clock or affect the kernel time variables. I suspect this approach also improves results when using an NTP server too.

Updating drift values

Use adjtimex --review to see the recommended values for /etc/adjtime using the cmos suggested adjustment; and the values for /etc/default/adjtimex using the sys suggested tick and frequency values.

Update (or create, if it does not exist), /etc/adjtime with:

    # hwclock --systohc --localtime

Use the --utc parameter instead of --localtime if the hwclock should be maintained using UTC/GMT.

Edit the first value on the first line to correspond with the value reported by adjtimex. Ensure you maintain the same precision for the value, i.e. make sure it has a total width of 8 characters including the decimal point. After adjusting, check the values match by running adjtimex --review again.

Unfortunately, this value will be overwritten by /etc/init.d/hwclock.sh when it also performs hwclock --systohc during suspend, shutdown etc. By making this change just before a such an event, the value should remain close to that intended.

Change the system clock drift values, e.g:

    # adjtimex --tick 1000 --frequency 6553600

To ensure these values are used on startup, modify the values for TICK and FREQ in /etc/default/adjtimex.

After changing these values, run another adjtimex --watch or adjtimex --host to start gathering stats again.

Files

Debian stores the host's time zone in /etc/timezone.

Whether the hardware clock is set to UTC or local time is specified in /etc/default/rcS as the 'UTC' setting. See also /etc/init.d/hwclock.sh

/etc/adjtime is used to calibrate the hardware clock.

/etc/default/adjtimex specifies the tick and frequency to be used for the system clock during startup.

/var/log/clocks stores the reference times used by adjtimex to recommend tick and frequency values.

References

-- Frank Dean - 2 Jan 2011

Related Topics: LinuxHintsAndTips