SDB:Configuring the clock
Situation
The clock shown e.g. with the date command is wrong after reboot. Sometimes the time stamps shown for some files are wrong, that is back in history or forward into the future. At boot the file systems may be checked without any apparent reason.
Background
Local time
During installation of a Linux system most users will be asked about the time to use for the CMOS/BIOS clock. At this time most users will intentionally choose local time as shown e.g. on a wrist watch. It is recommend that the system clock (as well as the CMOS/BIOS clock) is set to UTC/GMT. This way Linux can keep the user space clock on the correct time when the change for Daylight Saving Time occurs. The safest way is to set the CMOS clock to UTC before beginning the installation process.
Coordinated Universal Time
UTC (Coordinated Universal Time) is the international time standard. It is the current term for what was commonly referred to as Greenwich Meridian Time (GMT). Zero hours UTC is midnight in Greenwich, England, which lies on the zero longitudinal meridian. Coordinated Universal Time is based on a 24 hour clock; therefore, afternoon hours such as 4 pm UTC are expressed as 16:00 UTC.
User space
To understand why local time in CMOS clock may cause problems it helps to know which clock is used as reference by the Linux kernel and how the user space tools access this clock. Every application like the user space tool will first use e.g. the system call time(2) to determine seconds since the Epoch (00:00:00 UTC, January 1, 1970). This number now will be converted with the help of the glibc API functions ctime(3), gmtime(3) and localtime(3) to return the local time.
To convert the seconds since the Epoch the glibc API functions require the information of the timezone, that is, which time zone offset from UTC is used for local time and what rules like Daylight Saving Time (DST) must be applied.
All this timezone information is stored below /usr/share/zoneinfo/, e.g. /usr/share/zoneinfo/US/Central of /usr/share/zoneinfo/Europe/Berlin. To apply such a rule the environment variable TZ can be used like:
or for all applications running in a shell session
export TZ
of for (t)csh users
which will then declare the timezone for all commands after this definition in the current shell session.
To choose a timezone for all applications currently running in the user space, the glibc API functions also search for a file
/etc/localtime
This can be a symbolic link to one of the zonedate files below /usr/share or, if the /usr has its own partition, a copy of a zonedate file below /usr/share/zoneinfo/, note that when you do this, you will need to update your initial ramdisk regardless if the change has been done through command line or YAST.
Kernel space
Now the question arises: From where does the kernel know about the seconds since the Epoch as 00:00:00 UTC, January 1, 1970? On boot the kernel reads this information from the firmware clock like the BIOS/CMOS. With this the following scheme for the correct localtime in user space is seen:
[CMOS clock] -> [System Clock of the kernel in UTC] | v [glibc] <- /etc/localtime or TZ environment variable | v [localtime in user space]
To make this work and as the kernel does not have any information about the locatime and its timezone rules like timezone offsets and other rules, the CMOS/BIOS clock should naturally be set to UTC.
Hardware clock
On some systems there is more than one Operating System (OS) and some of the other OS may not handle the UTC as natural clock reference. This may require to the choice of localtime for the CMOS/BIOS clock, but this has two drawbacks:
- The Linux kernel has to informed about this fact, and this before any file system will be accessed, potentially by a file system check, and before such file system will be mounted, to apply correct file system time stamps. Compare with the mail The ext3 way of journallingof the thread found at https://lkml.org.
- The CMOS/BIOS clock does not know about Daylight Saving Time switches. This may change with the new UEFI BIOS approach.
Initrd RAM disk
To solve the first drawback, the Linux kernel's system clock can be informed by the system call settimeofday(2) which timezone offset should be used. This requires as settimeofday(2) is also part of the glibc that the information in /etc/localtime and also of /usr/share/zoneinfo/UTC is available before the root file system is accessed.
For this the files /etc/localtime and /usr/share/zoneinfo/UTC are stored together with the tool warpclock below /lib/mkinitrd/ in the initrd(4), the initial boot loader RAM disk. The above scheme now becomes more complex:
[CMOS clock] -> [System Clock of the kernel in localtime] ^ | +- [initrd warpclock <- (initrd)/etc/localtime] | v [System Clock of the kernel in UTC] | v [glibc] <- /etc/localtime or TZ environment variable | v [localtime in user space]
The remaining drawback is that the CMOS/BIOS clock has to be changed at Daylight Saving Time switches. This can be done by the System Administrator or by booting the Windows[tm] system, which stores the switch deeply in its Windows[tm] registry (with the drawback that no other OS knows about its CMOS/BIOS clock correction).
Conclusion
Now about which time reference should be used for the BIOS/CMOS clock:
- On a single boot system with Linux only UTC seems to be the only natural reference. This is because the CMOS/BIOS clock does not require any maintenance any more due to Daylight Saving Time switches.
- On a multiboot system with any OS not able to handle UTC in CMOS/BIOS clock, the only choice is localtime.
The last choice requires some more accuracy to hold the information about timezone and CMOS clock in the initrd in sync with the current setup. That is that every change of the timezone requires not only change of the CMOS clock but also a refresh of the initrd before any file system will be accessed on the next reboot.
Other OS
For Vista[tm] SP2, Windows[tm] 7 and Server 2008 R2 the System Administrator of those Windows[tm] systems could create a file with extension .reg, e.g. named utc.reg:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation] "RealTimeIsUniversal"=dword:00000001
and then double click on it to merge its contents with the Windows[tm] registry. With this it could be possible to use for both those Windows[tm] systems and the Linux system UTC as reference the CMOS clock. It has been reported that Vista[tm] SP2 does not handle Daylight Saving Time switches.
Compare with external link IBM PC Real Time Clock should run in UT.
Next problems can be Enhanced Write Filter and File-Based Write Filter in Windows[tm]. Therefore the above procedure become more complicated
- Make sure that Enhanced Write Filter and File-Based Write Filter are disabled.
- Setup the time zone which should be used by Windows[tm].
- Restart Windows[tm] and switch into the CMOS setup to set the clock to current UTC time and date
- Boot into Windows[tm] and (re)enable Enhanced Write Filter and File-Based Write Filter.
Compare with external link Computer Time Management and Embedded Systems (Windows Embedded Standard 7 Service Pack 1).