Clock adjusting in SuSE Linux micro-howtoEvery PC has two clocks. One is a software clock, that counts timer interrupts (19.2 per second); this is the only clock used by the operating system. The original PC had only this clock, so it had to ask the user for the current time and date on every boot to be set properly. Then, somebody [1] designed an ISA card with a battery clock that the system could read on boot and initialize the software clock. The AT computer type had a chip with a clock, some memory and an external backup battery. It was a CMOS chip; sounds familiar? Yes, that is also where BIOS configuration is stored. Therefore, all current PCs have also a hardware clock, with a battery, that runs even when the computer is unpowered, used to update the software (aka system) clock. The system clock is set internally to UTC[2]; when asked to display the time, it converts it to local time. The CMOS on a Linux system should be UTC. However, we can set it also to localtime, specially if we double boot to some other OS. That is a special case that has to be considered on boot. A digital clock is always precise: there can be no doubt about the time it says it is. Being precise is not the same as being accurate, however: the time it says to be can be incorrect. Some definitions apply; I'll paste here what I found on The Free On-line Dictionary of Computing (27 SEP 03):
The software clock might be inacurate, drift erratically, if the OS looses interrupts (note: I say might). However, every quartz based electronic clock may be inacurate, but it is always the same inacuracy: that is, it is always fast or slow by the same amount - or at least almost so. Therefore, if we know that amount by comparison to an external reference, we can make use of the fact that it is installed on a computer, and calculate and compensate for that constant drift. That is what the program hwclock does, amongst other things, keeping the adjustment in /etc/adjtime. Pity we can not do the same for our ordinary clock and watches. For the purpose of this writeup, use only the command date on a console or terminal. Don't even look at desktop gadgets, because sometimes they could be wrong (buggy) and confuse us. For example: nimrodel:˜ # hwclock --show ; date ; date -u Thu Dec 11 03:54:53 2003 -0.885510 seconds Thu Dec 11 03:54:41 CET 2003 Thu Dec 11 02:54:41 UTC 2003 The commands above show, in succession, the CMOS time (localtime unless specified), the local system time, and UTC system time. This document is based on SuSE 8.2 - but the system has been basically the same for some years, and I assume it is the same as on SuSE 9.0. The script /etc/init.d/boot.clock is responsible for setting up the clock during boot - read it for details. It takes some configuration from /etc/sysconfig/clock (or /etc/rc.config on older SuSE versions). I'll excerpt here the important parts. If we have a s390 computer, and the CMOS clock is set to localtime, this is executed: if test "$HWCLOCK" != "-u"; then date $(date -u +'%m%d%H%M%Y') rc_status fi Not too neat, perhaps a “hack”. After all, a Linux system should use UTC ;-) Otherwise, for the rest of PCs, this is executed to set up the clock:
echo -n Setting up the CMOS clock
test -f /etc/adjtime || echo “0.0 0 0.0” > /etc/adjtime
/sbin/hwclock --adjust $HWCLOCK
rc_status
/sbin/hwclock --hctosys $HWCLOCK
First, if the file /etc/adjtime does not exist, it is recreated with default valued (that's why if the adjust is going wrong, simply deleting that file works). Then, the hardware clock is adjusted (compensated) for its known constant drift. Finally, the system clock is set up from the hardware clock. Simple :-) The script /etc/init.d/halt does many things, and one of them is: echo "Sending all processes the KILL signal..." killall -9 echo -e "$rc_done_up" if test "$HOSTTYPE" = "s390" ; then HWCLOCK_ACCESS=no fi if test "$HWCLOCK_ACCESS" != "no" ; then if rc_active xntpd ; then echo -n "Set Hardware Clock to the current System Time" # write back to hardware clock and calculate adjtime /sbin/hwclock --systohc $HWCLOCK rc_status -v -r fi fi What is that? Well, it checks to see if xntpd daemon was defined to run, and if so it assumes the system clock is correct, and therefore finally copies it back to the hardware (CMOS) clock, and calculates the drift to consider. If we setup the system clock with date or a similar command we'll have problems, because the hardware clock is not synchronized. If we synchronize it incorrectly, the system is set up in such a way that it might think that is the constant drift it has to add on every boot, and the clock will be set up wrongly every boot up. There is a sequence of events that has to be respected. This method can be used in cases where we don't have a permanent network connection, only a temporary one (or we don't want to run the daemon for whatever reasons). The sequence is:
For example, it can be inserted in /etc/ppp/ip-up.local script and it will run automatically every time we connect using the modem: SERVICE_NAME=ip-up.local NTPDATEOUT=/etc/ppp/ntpdate.output /etc/init.d/xntpd ntptimeset &/bin/logger -t $SERVICE_NAME -p user.info " --> Synchronizing time"> $NTPDATEOUT . /etc/sysconfig/clock /sbin/hwclock --systohc $HWCLOCK /bin/logger -t $SERVICE_NAME -p user.info -f $NTPDATEOUT For this to run, we have to previously edit the file /etc/ntp.conf, where we only need to insert the time servers we'll use as references: ## Outside source of synchronized time ## server ntp.host.domain # address of server 1 server ntp.host2.domain # address of server 2 What we do is, first obtain the time form the best of external time servers taken form a list to update the system time. Secondly we update the hardware clock. The extra lines are “beautifiers”. So, first we make a call to rcxntpd ntptimeset - this is equivalent to calling /usr/sbin/ntpdate -su server_list. The advantage is that
If we don't have a network connection, we'll have to make do with the command date and a radio for refence. The second step is to synchronise the hardware clock, taking into account whether it uses local or UTC time[3]. The ntpd daemon will adjust the clock slowly, so that the system is not altered. However, the ntpdate command will adjust time suddenly if the error is bigger than 128ms. If the clock jump some seconds strange, or even bad, things can occur. Therefore, ntpd is safer - but we may not have a permanent network connection, and synchronization can take hours. Setting the clock fast is something usually done during computer initialisation (booting up) so that the daemon has an easier job. However, if we don't have a permanent network connection, using ntpdate is our only way - possibly using the -B parameter, which will force it to slew instead of step the clock. That is something I'm currently testing. Delete file /etc/adjtime after adjusting both system and hardware clock as explained above. Don't worry, it will be recreated on next boot. Configure and start service rcxntpd - you can use Yast runlevel editor to enable this. I understand you can also use Yast to configure this service on SuSE 9.0, but certainly not on previous versions. You will have to look elsewhere for information or details on configuring and running this service: a permanent network connection is needed, and I don't have one. You can obtain the list of servers names from http://www.eecis.udel.edu/˜mills/ntp/servers.html - don't choose stratum 1 servers, unless you are going to set up a public NTP server - and in that case, this document shouldn't be your main source of information. Also, we can obtain servers names from a pool of servers, using one or more lines like this one in the /etc/ntpd.conf file: server es.pool.ntp.org server europe.pool.ntp.org I don't know how this pool works, I haven't found it documented in the ntpd docs yet. However, I have seen it on the SLE and the Spanish document mentioned in the further reading section below.
[1] Who he was I don't currently know [2] The acronym UTC (Universal Coordinated Time) has that strange order on purpose, neither English or French (or Spanish) ordering. It is to preferred to the equivalent GMT (Greenwich Meridian Time), which is considered deprecated. [3] Notice that ntp servers always give UTC time, not local time. The conversion to local time is the responsibility of your software or OS. | |