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.
- Use the NTP daemon from the ntp package if you have constant access to one or more NTP servers
- Use the chrony daemon from the chrony package if you have intermittent or no access to an NTP server
- 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:
Read
/usr/share/doc/util-linux/README.Debian.hwclock
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.)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
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 thathwclock --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.)
Enter the following command:
# adjtimex --watch
Press the
enter
key when you know the time of day.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.Either enter the possible amount of error for the time provided, or 'r' to retry or 'q' to quit.
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
/usr/share/doc/util-linux/README.Debian.hwclock
man hwclock
man adjtimex
-- Frank Dean - 2 Jan 2011
Related Topics: LinuxHintsAndTips