A Linux system actually has two clocks: One is the battery
powered "Real Time Clock" (also known as the
"RTC", "CMOS clock", or "Hardware
clock") which keeps track of time when the system is turned
off but is not used when the system is running. The other is the
"system clock" (sometimes called the "kernel
clock" or "software clock") which is a software
counter based on the timer interrupt. It does not exist when the
system is not running, so it has to be initialized from the RTC
(or some other time source) at boot time. References to
"the clock" in the ntpd
documentation refer
to the system clock, not the RTC.
The two clocks will drift at different rates, so they will
gradually drift apart from each other, and also away from the
"real" time. The simplest way to keep them on time is to
measure their drift rates and apply correction factors in
software. Since the RTC is only used when the system is not
running, the correction factor is applied when the clock is
read at boot time, using clock(8)
or hwclock(8)
.
The system clock is corrected by adjusting the rate at which the system
time is advanced with each timer interrupt, using adjtimex(8)
.
A crude alternative to adjtimex(8)
is to have
chron
run clock(8)
or hwclock(8)
periodically to sync the system time to the (corrected) RTC. This
was recommended in the clock(8)
man page, and it works
if you do it often enough that you don't cause large
"jumps" in the system time, but adjtimex(8)
is a more elegant solution. Some applications may complain if the
time jumps backwards.
The next step up in accuracy is to use a program like
ntpd
to read the time periodically from a network time
server or radio clock, and continuously adjust the rate of the
system clock so that the times always match. If you always have a
network connection at boot time, you can ignore the RTC
completely and use ntpdate
(which comes with the
ntpd
package) to initialize the system clock from the
time server-- either a local server on a LAN, or a remote server
on the internet. But if you sometimes don't have a network
connection, or if you need the time to be accurate during the
boot sequence before the network is active, then you need to
maintain the time in the RTC as well.
It might seem obvious that in this case you would want to sync the RTC to the (corrected) system clock. But this turns out to be a bad idea if the system is going to stay shut down longer than a few minutes, because it interferes with the programs that apply the correction factor to the RTC at boot time.
If the system runs 24/7 and is always rebooted immediately whenever it's shut down, then you can just set the RTC from the system clock right before you reboot. The RTC won't drift enough to make a difference in the time it takes to reboot, so you don't have to know its drift rate.
Of course the system may go down unexpectedly, so some versions of the kernel sync the RTC to the system clock every 11 minutes if the system clock has been adjusted by another program. The RTC won't drift enough in 11 minutes to make any difference, but if the system is down long enough for the RTC to drift significantly, then you have a problem: the programs that apply the drift correction to the RTC need to know *exactly* when it was last reset, and the kernel doesn't record that information anywhere.
Some unix "traditionalists" might wonder why anyone would run a linux system less than 24/7, but some of us run dual-boot systems with another OS running some of the time, or run Linux on laptops that have to be shut down to conserve battery power when they're not being used. Other people just don't like to leave machines running unattended for long periods of time (even though we've heard all the arguments in favor of it). So, the "every 11 minutes" feature becomes a bug.
This "feature/bug" appears to behave differently in
different versions of the kernel (and possibly in different
versions of xntpd
and ntpd
as well), so if
you're running both ntpd
and hwclock
you may
need to test your system to see what it actually does. If you
can't keep the kernel from resetting the RTC, you might have to
run without a correction factor.
The part of the kernel that controls this can be found in
/usr/src/linux-2.0.34/arch/i386/kernel/time.c
(where the version number in the path will be the version of the
kernel you're running). If the variable time_status
is
set to TIME_OK
then the kernel will write the system
time to the RTC every 11 minutes, otherwise it leaves the RTC
alone. Calls to adjtimex(2)
(as used by ntpd
and timed
, for example) may turn this on. Calls to
settimeofday(2)
will set time_status
to
TIME_UNSYNC
, which tells the kernel not to adjust the
RTC. I have not found any real documentation on this.
If you don't need sub-second accuracy, hwclock(8)
and
adjtimex(8)
may be all you need. It's easy to get
enthused about radio clocks and such, but I ran the old
clock(8)
program for years with excellent results. On
the other hand, if you have several machines on a LAN it can be
handy to have them automatically sync their clocks to each other.