<chapter id="keeping-time">
<title>Keeping Time</title>

	<blockquote><para><quote>Time is an illusion.  Lunchtime double
	so.</quote> (Douglas Adams.)</para></blockquote>

	<para> This chapter explains how a Linux system keeps time,
	and what you need to do to avoid causing trouble.  Usually,
	you don't need to do anything about time, but it is good to
	understand it.</para>

<sect1 id="localtime">
<title>The concept of localtime</title>

	<para> Time measurement is based on mostly regular natural
	phenomena, such as alternating light and dark periods caused
	by the rotation of the planet. The total time taken by two
	successive periods is constant, but the lengths of the light
	and dark period vary. One simple constant is noon.  </para>

	<para> Noon is the time of the day when the Sun is at its
	highest position.  Since (according to recent research) the Earth is 
	round, noon happens at different times in different places.  This 
	leads to the concept of <glossterm>local time</glossterm>.  Humans
	measure time in many units, most of which are tied to natural
	phenomena like noon.  As long as you stay in the same place,
	it doesn't matter that local times differ.  </para>

	<para> As soon as you need to communicate with distant places,
	you'll notice the need for a common time.  In modern times,
	most of the places in the world communicate with most other
	places in the world, so a global standard for measuring time
	has been defined.  This time is called <glossterm>universal
	time</glossterm> (UT or UTC, formerly known as Greenwich Mean Time
	or GMT, since it used to be local time in Greenwich, England).
	When people with different local times need to communicate,
	they can express times in universal time, so that there is no
	confusion about when things should happen.  </para>
	
	<para> Each local time is called a time zone.  While geography
	would allow all places that have noon at the same time have the
	same time zone, politics makes it difficult.  For various reasons,
	many countries use <glossterm>daylight savings time</glossterm>,
	that is, they move their clocks to have more natural light
	while they work, and then move the clocks back during winter.
	Other countries do not do this.  Those that do, do not agree when
	the clocks should be moved, and they change the rules from year
	to year.  This makes time zone conversions definitely non-trivial.
	</para>
	
	<para> Time zones are best named by the location or by telling
	the difference between local and universal time.  In the US
	and some other countries, the local time zones have a name and
	a three letter abbreviation.  The abbreviations are not unique,
	however, and should not be used unless the country is also named.
	It is better to talk about the local time in, say, Helsinki,
	than about East European time, since not all countries in Eastern
	Europe follow the same rules.  </para>
	
	<para> Linux has a time zone package that knows about all
	existing time zones, and that can easily be updated when the
	rules change.  All the system administrator needs to do is to
	select the appropriate time zone.  Also, each user can set his
	own time zone; this is important since many people work with
	computers in different countries over the Internet.  When the
	rules for daylight savings time change in your local time zone,
	make sure you'll upgrade at least that part of your Linux system.
	Other than setting the system time zone and upgrading the time
	zone data files, there is little need to bother about time.
	</para>

</sect1>

<sect1 id="hw-sw-clocks">
<title>The hardware and software clocks</title>

	<para> A personal computer has a battery driven hardware clock.
	The battery ensures that the clock will work even if the rest of
	the computer is without electricity.  The hardware clock can be
	set from the BIOS setup screen or from whatever operating system
	is running.  </para>
	
	<para> The Linux kernel keeps track of time independently from
	the hardware clock.  During the boot, Linux sets its own clock
	to the same time as the hardware clock.  After this, both clocks
	run independently.  Linux maintains its own clock because looking
	at the hardware is slow and complicated.  </para>

	<para> The kernel clock always shows universal time.  This way,
	the kernel does not need to know about time zones at all. The
	simplicity results in higher reliability and makes it easier
	to update the time zone information.  Each process handles time
	zone conversions itself (using standard tools that are part of
	the time zone package).  </para>
	
	<para> The hardware clock can be in local time or in universal
	time.  It is usually better to have it in universal time,
	because then you don't need to change the hardware clock when
	daylight savings time begins or ends (UTC does not have DST).
	Unfortunately, some PC operating systems, including MS-DOS,
	Windows, and OS/2, assume the hardware clock shows local time.
	Linux can handle either, but if the hardware clock shows local
	time, then it must be modified when daylight savings time begins
	or ends (otherwise it wouldn't show local time).  </para>

</sect1>

<sect1 id="showing-setting-time">
<title>Showing and setting time</title>

	<para> In Linux, the system time zone is determined
	by the symbolic link <filename>/etc/localtime</filename>.
	This link points to a time zone data file that describes
	the local time zone.  The time zone data files are located at 
	either <filename>/usr/lib/zoneinfo</filename> or 
	<filename>/usr/share/zoneinfo</filename> depending on what distribution
	of Linux you use.</para>
	
	<para> For example, on a SuSE system located in New Jersey the 
	<filename>/etc/localtime</filename> link would point to 
	<filename>/usr/share/zoneinfo/US/Eastern</filename>.  On a Debian system
	the <filename>/etc/localtime</filename> link would point to
	<filename>/usr/lib/zoneinfo/US/Eastern</filename>.</para>

	<para> If you fail to find the <filename>zoneinfo</filename> 
	directory in either the <filename>/usr/lib</filename> or 
	<filename>/usr/share</filename> directories, either do a 
	<command>find /usr -print | grep zoneinfo</command> or consult 
	your distribution's documentation.
	</para>
	
	<para> What happens when you have a users located in a different
	timezone?  A user can change his private time zone by setting the
	TZ environment variable.  If it is unset, the system time zone
	is assumed. The syntax of the TZ variable is described in the
	<function>tzset</function> manual page.  </para>
	
	<para>
	The <command>date</command> command shows the current date and 
	time.
	
	For example:

<screen>
<prompt>$</prompt> <userinput>date</userinput>
<computeroutput>Sun Jul 14 21:53:41 EET DST 1996</computeroutput>
<prompt>$</prompt>
</screen>

	That time is Sunday, 14th of July, 1996, at about ten before
	ten at the evening, in the time zone called ``EET DST''
	(which might be East European Daylight Savings Time).
	<command>date</command> can also show the universal time:

<screen>
<prompt>$</prompt> <userinput>date -u</userinput>
<computeroutput>Sun Jul 14 18:53:42 UTC 1996</computeroutput>
<prompt>$</prompt>
</screen>

	<command>date</command> is also used to set the kernel's software 
	clock:

<screen>
<prompt>#</prompt> <userinput>date 07142157</userinput>
<computeroutput>Sun Jul 14 21:57:00 EET DST 1996</computeroutput>
<prompt>#</prompt> <userinput>date</userinput>
<computeroutput>Sun Jul 14 21:57:02 EET DST 1996</computeroutput>
<prompt>#</prompt>
</screen>

	See the <command>date</command> manual page for more details;
	the syntax is a bit arcane.  Only root can set the time.
	While each user can have his own time zone, the clock is the
	same for everyone.  </para>

	<para>Beware of the <command>time</command> command.  This is not
	used to get the system time.  Instead it's used to time how long 
	something takes.  Refer to the time man page.</para>
	
	<para> <command>date</command> only shows or sets the software
	clock.	The <command>clock</command> commands synchronizes
	the hardware and software clocks.  It is used when the system
	boots, to read the hardware clock and set the software clock.
	If you need to set both clocks, you first set the software clock
	with <command>date</command>, and then the hardware clock with
	<command>clock -w</command>.  </para>

	<para> The <option>-u</option> option to <command>clock</command>
	tells it that the hardware clock is in universal time.
	You <emphasis>must</emphasis> use the <option>-u</option>
	option correctly.  If you don't, your computer will be quite
	confused about what the time is.  </para>

	<para> The clocks should be changed with care.	Many parts of a
	Unix system require the clocks to work correctly.  For example,
	the <command>cron</command> daemon runs commands periodically.
	If you change the clock, it can be confused of whether
	it needs to run the commands or not.  On one early Unix
	system, someone set the clock twenty years into the future,
	and <command>cron</command> wanted to run all the periodic
	commands for twenty years all at once.	Current versions of
	<command>cron</command> can handle this correctly, but you should
	still be careful.  Big jumps or backward jumps are more dangerous
	than smaller or forward ones.  </para>

</sect1>

<sect1 id="clock-wrong">
<title>When the clock is wrong</title>

	<para> The Linux software clock is not always accurate.  It is
	kept running by a periodic <glossterm>timer interrupt</glossterm>
	generated by PC hardware.  If the system has too many processes
	running, it may take too long to service the timer interrupt, and
	the software clock starts slipping behind.  The hardware clock
	runs independently and is usually more accurate.  If you boot
	your computer often (as is the case for most systems that aren't
	servers), it will usually keep fairly accurate time.  </para>
	
	<para> If you need to adjust the hardware clock, it is usually
	simplest to reboot, go into the BIOS setup screen, and do it
	from there.  This avoids all trouble that changing system time
	might cause.  If doing it via BIOS is not an option, set the new
	time with <command>date</command> and <command>clock</command>
	(in that order), but be prepared to reboot, if some part of the
	system starts acting funny.  </para>

	<para> Another method would be to use either <command>hwclock -w</command>
	or <command>hwclock --systohc</command> to sync the hardware clock
	to the software clock.  If you want to sync your software clock to your 
	hardware clock then you would use <command>hwclock -s</command> or 
	<command>hwclock --hwtosys</command>.  For more information on this 
	command read <command>man hwclock</command>.</para>

	<!-- Commented out to add NTP info.
	<para> A networked computer (even if just over the modem) can
	check its own clock automatically, by comparing it to some other
	computer's time.  If the other computer is known to keep very
	accurate time, then both computers will keep accurate time.
	This can be done by using the <command>rdate</command> and
	<command>netdate</command> commands.  Both check the time of a
	remote computer (<command>netdate</command> can handle several
	remote computers), and set the local computer's time to that.
	By running one these commands regularly, your computer will keep
	as accurate time as the remote computer.  </para>

	<para> XXX say something intelligent about NTP </para> -->
</sect1>

<sect1 id="ntp">
<title>NTP - Network Time Protocol</title>

	<para> A networked computer (even if just over a modem) can
        check its own clock automatically by comparing it to the time
        on another computer known to keep accurate time.  Network Time 
	Protocol (or NTP) does exactly that. It is a method of verifying 
	and correcting your computer's time by synchronizing it with a 
	another system. With NTP your system's time can be maintained 
	to within milliseconds of Coordinated Universal Time.  Visit
	<ulink url="http://www.time.gov/about.html/">
	http://www.time.gov/about.html</ulink> for more info.
	</para>
	
	<para> For more casual Linux users, this is just a nice luxury.  
	At my home all our clocks are set based upon what my Linux system 
	says the time is.  For larger organizations this "luxury" can 
	become essential.  Being able to search log files for events based 
	upon time can make life a lot easier and take a lot of the "guess work"
	out of debugging.
	</para>
	
	
	<para> Another example of how important NTP can be is with a SAN.  
	Some SAN's require NTP be configured and running properly to allow 
	for proper synchronization over filesystem usage, and proper 
	timestamp control.  Some SANs (and some applications) can become 
	confused when dealing with files that have timestamps that are in 
	the future.
	</para>

	<para> Most Linux distributions come with a NTP package of some kind,
	either a .deb or .rpm package.  You can use that to install NTP, or you 
	can download the source files from <ulink url="http://www.ntp.org/downloads.html">
	http://www.ntp.org/downloads.html</ulink> and compile it yourself.  Either way, 
	the basic configuration is the same.</para>
</sect1>	

<sect1 id="basic-ntp-config">
<title>Basic NTP configuration</title>
	<para>The NTP program is configured using either the 
	<filename>/etc/ntp.conf	</filename> or <filename>/etc/xntp.conf</filename> 
	file depending on what distribution of Linux you have.  I won't go 
	into too much detail on how to configure NTP.  Instead I'll just 
	cover the basics.</para>
	
	<para>An example of a basic ntp.conf file would look like:

<screen>
<computeroutput># --- GENERAL CONFIGURATION ---
server  aaa.bbb.ccc.ddd
server  127.127.1.0
fudge   127.127.1.0 stratum 10

# Drift file.

driftfile /etc/ntp/drift
</computeroutput>
	</para>

	<para>The most basic ntp.conf file will simply list 2 servers, one 
	that it wishes to synchronize with, and a pseudo IP address for
	itself (in this case 127.127.1.0). The pseudo IP is used in case of 
	network problems or if the remote NTP server goes down. NTP will 
	synchronize against itself until the it can start synchronizing with 
	the remote server again.  It is recommended that you list at 
	least 2 remote servers that you can synchronize against.  One will 
	act as a primary server and the other as a backup.</para>

	<para>You should also list a location for a drift file.  Over time
	NTP will "learn" the system clock's error rate and automatically 
	adjust for it.</para>

	<para>The restrict option can be used to provide better control and
	security over what NTP can do, and who can effect it.  For example:

<screen>
<computeroutput># Prohibit general access to this service.
restrict default ignore

# Permit systems on this network to synchronize with this
# time service. But not modify our time.
restrict aaa.bbb.ccc.ddd nomodify

# Allow the following unrestricted access to ntpd

restrict aaa.bbb.ccc.ddd
restrict 127.0.0.1
</computeroutput>
</screen>

	It is advised that you wait until you have NTP working properly before
	adding the restrict option.  You can accidental restrict yourself from
	synchronizing and waste time debugging why.
	</para>

	<para>NTP slowly corrects your systems time.  Be patient!  A simple test
	is to change your system clock by 10 minutes before you go to bed and then
	check it when you get up.  The time should be correct.</para>
	
	<para>Many people get the idea that instead of running the NTP
	daemon, they should just setup a <command>cron</command> job 
	job to periodically run the <command>ntpdate</command> command.
	There are 2 main disadvantages of using this method.</para>

	<para>The first is that <command>ntpdate</command> does a "brute force"
	method of changing the time.  So if your computer's time is off my 5 
	minutes, it immediately corrects it.  In some environments, this can 
	cause problems if time drastically changes.  For example, if you are 
	using time sensitive security software, you can inadvertently kill
	someones access.  The NTP daemon slowly changes the time to avoid 
	causing this kind of disruption.</para>

	<para>The other reason is that the NTP daemon can be configured to
	try to learn your systems <glossterm>time drift</glossterm> and 
	then automatically adjust for it.</para> 

</sect1>

<sect1 id="ntp-toolkit">
<title>NTP Toolkit</title>
	<para>There are a number of utilities available to check if
	NTP is doing it's job. The <command>ntpq -p</command> command
	will print out your system's current time status.

<screen>
<prompt>#</prompt> <userinput>ntpq -p</userinput>
<computeroutput>     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*cudns.cit.corne ntp0.usno.navy.  2 u  832 1024  377   43.208    0.361   2.646
 LOCAL(0)        LOCAL(0)        10 l   13   64  377    0.000    0.000   0.008
</computeroutput>
</screen>
	</para>

	<para> The <command>ntpdc -c loopinfo</command> will display 
	how far off the system time is in seconds, based upon the last time
	the remote server was contacted.

<screen>
<prompt>#</prompt> <userinput>ntpdc -c loopinfo</userinput>
<computeroutput>offset:               -0.004479 s
frequency:            133.625 ppm
poll adjust:          30
watchdog timer:       404 s
</computeroutput>
	</para>

	<para><command>ntpdc -c kerninfo</command> will display 
	the current remaining correction.

<screen>
<prompt>#</prompt> <userinput>ntpdc -c kerninfo</userinput>
<computeroutput>pll offset:           -0.003917 s
pll frequency:        133.625 ppm
maximum error:        0.391414 s
estimated error:      0.003676 s
status:               0001  pll
pll time constant:    6
precision:            1e-06 s
frequency tolerance:  512 ppm
pps frequency:        0.000 ppm
pps stability:        512.000 ppm
pps jitter:           0.0002 s
calibration interval: 4 s
calibration cycles:   0
jitter exceeded:      0
stability exceeded:   0
calibration errors:   0
</computeroutput>
	</para>

	<para> A slightly more different version of 
	<command>ntpdc -c kerninfo</command> is <command>ntptime</command>
<screen>
<prompt>#</prompt> <userinput>ntptime</userinput>
<computeroutput>ntp_gettime() returns code 0 (OK)
  time c35e2cc7.879ba000  Thu, Nov 13 2003 11:16:07.529, (.529718),
  maximum error 425206 us, estimated error 3676 us
ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset -3854.000 us, frequency 133.625 ppm, interval 4 s,
  maximum error 425206 us, estimated error 3676 us,
  status 0x1 (PLL),
  time constant 6, precision 1.000 us, tolerance 512 ppm,
  pps frequency 0.000 ppm, stability 512.000 ppm, jitter 200.000 us,
  intervals 0, jitter exceeded 0, stability exceeded 0, errors 0.
</computeroutput>
</screen>
	</para>

	<para> Yet another way to see how well NTP is working is 
	with the <command>ntpdate -d</command> command.	This will 
	contact an NTP server and determine the time difference
	but not change your system's time.

<screen>
<prompt>#</prompt> <userinput>ntpdate -d 132.236.56.250</userinput>
<computeroutput>13 Nov 14:43:17 ntpdate[29631]: ntpdate 4.1.1c-rc1@1.836 Thu Feb 13 12:17:20 EST 2003 (1)
transmit(132.236.56.250)
receive(132.236.56.250)
transmit(132.236.56.250)
receive(132.236.56.250)
transmit(132.236.56.250)
receive(132.236.56.250)
transmit(132.236.56.250)
receive(132.236.56.250)
transmit(132.236.56.250)
server 132.236.56.250, port 123
stratum 2, precision -17, leap 00, trust 000
refid [192.5.41.209], delay 0.06372, dispersion 0.00044
transmitted 4, in filter 4
reference time:    c35e5998.4a46cfc8  Thu, Nov 13 2003 14:27:20.290
originate timestamp: c35e5d55.d69a6f82  Thu, Nov 13 2003 14:43:17.838
transmit timestamp:  c35e5d55.d16fc9bc  Thu, Nov 13 2003 14:43:17.818
filter delay:  0.06522  0.06372  0.06442  0.06442
         0.00000  0.00000  0.00000  0.00000
filter offset: 0.000036 0.001020 0.000527 0.000684
         0.000000 0.000000 0.000000 0.000000
delay 0.06372, dispersion 0.00044
offset 0.001020

13 Nov 14:43:17 ntpdate[29631]: adjust time server 132.236.56.250 offset 0.001020 sec
</computeroutput>
</screen>
	</para>

	<para> If you want actually watch the system
	synchronize you can use <command>ntptrace</command>.

<screen>
<prompt>#</prompt> <userinput>ntptrace 132.236.56.250</userinput>
<computeroutput>cudns.cit.cornell.edu: stratum 2, offset -0.003278, synch distance 0.02779
truetime.ntp.com: stratum 1, offset -0.014363, synch distance 0.00000, refid 'ACTS'</computeroutput>
</screen>
	</para>
<!-- for reference
<screen>
<prompt>#</prompt> <userinput></userinput>
<computeroutput></computeroutput>
</screen>
-->

	<para>If you need your system time synchronized immediately 
	you can use the <command>ntpdate remote-servername</command> 
	to force a synchronization.  No waiting!

<screen>
<prompt>#</prompt> <userinput>ntpdate 132.236.56.250</userinput>
13 Nov 14:56:28 ntpdate[29676]: adjust time server 132.236.56.250 offset -0.003151 sec
<computeroutput></computeroutput>
</screen>
</para>

</sect1>

<sect1 id="ntp-servers">
<title>Some known NTP servers</title>
		<para>A list of public NTP servers can be obtained from:
	<ulink url="http://www.eecis.udel.edu/~mills/ntp/servers.html/">
	http://www.eecis.udel.edu/~mills/ntp/servers.html</ulink>.  Please read
	the usage information on the page prior so using a server.  Not all
	servers have the available bandwidth to allow a large number of systems
	synchronizing against them.  Therefore it is a good idea to contact
	a system's administrator prior to using his/her server for NTP services.
	</para>
</sect1>

<sect1 id="ntp-links">
<title>NTP Links</title>
	<para>More detailed information on NTP can be obtained from the
	NTP homepage:<ulink url="http://www.ntp.org/">http://www.ntp.org</ulink>.
	</para>
	
	<para>Or from <ulink url="http://www.ntp.org/ntpfaq/NTP-a-faq.htm">
	http://www.ntp.org/ntpfaq/NTP-a-faq.htm</ulink></para>
</sect1>
</chapter>
