Monday, 17 December 2012

Correcting Unix Clock Drift on Hyper-V

I recently had a problem where my CentOS 5 virtual machine running on Hyper-V on Server 2008 R2 was gaining time quite dramatically.

Initially, I turned off "Time synchronization" in the Integration Services section of the Hyper-V settings for the CentOS virtual machine. This did help a bit, but it was still far to inaccurate and too much for NTP to correct.

After a bit of Googling, here is what I did to correct the clock inaccuracy problem:

Modify the kernel boot options by editing [/boot/grub/grub.conf] and adding the line "divider=10 clocksource=acpi_pm" (for 32-bit) or "notsc divider=10" (for 64-bit) after the appropriate kernel line, as below.


# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/hda5
#          initrd /initrd-version.img
#boot=/dev/hda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-308.20.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-308.20.1.el5 ro root=LABEL=/ selinux=0 notsc divider=10
        initrd /initrd-2.6.18-308.20.1.el5.img
title CentOS (2.6.18-274.17.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-274.17.1.el5 ro root=LABEL=/ selinux=0
        initrd /initrd-2.6.18-274.17.1.el5.img



Now to configure NTP, you might need to install it first with yum install ntp

The following is the [/etc/ntp.conf]. Note that you should normally change 0.centos.pool.ntp.org to something specific to your country, for example, 0.uk.pool.ntp.org, and the same for the other ntp servers here, and in [/etc/ntp/step-tickers] in below. See www.pool.ntp.org/en for more information on the NTP pool and which servers you should use.


tinker panic 0
restrict 127.0.0.1
restrict default kod nomodify notrap
server 0.uk.pool.ntp.org
server 1.uk.pool.ntp.org
server 2.uk.pool.ntp.org
server 3.uk.pool.ntp.org

# Dont use local clock
#server 127.127.1.0     # local clock
#fudge  127.127.1.0 stratum 10

# Drift file.
driftfile /var/lib/ntp/drift

# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys

# Specify the key identifiers which are trusted.
#trustedkey 4 8 42

# Specify the key identifier to use with the ntpdc utility.
#requestkey 8

# Specify the key identifier to use with the ntpq utility.
#controlkey 8



The conf directive "tinker panic 0" instructs NTP not to give up if it sees a large jump in time. This is important for coping with large time drifts and also resuming virtual machines from their suspended state. The directive "tinker panic 0" must be at the top of the ntp.conf file.

It is also important not to use the local clock as a time source, often referred to as the Undisciplined Local Clock. NTP has a tendency to fall back to this in preference to the remote servers when there is a large amount of time drift.
An example of such a configuration is:
server 127.127.1.0
fudge 127.127.1.0 stratum 10
Comment out both lines.

Now for the step tinker file. This is to get the time to synk up at a reboot and not rely on the hardware. So add / edit the file [/etc/ntp/step-tickers]:


0.uk.pool.ntp.org
1.uk.pool.ntp.org
2.uk.pool.ntp.org
3.uk.pool.ntp.org


Now everything is ready for the CentOS to look after it's self we just need to set the time correctly.


If you want to get the time closer set the time with the date command:
e.g. for 18th December 2012 at 10:00 am use
date 1218100012
This will stop ntp getting in a flap when the time is a long way off , and makes the correction quicker.
Then set the synchronise the time manually:
ntpd -q
Set the hardware clock to the newly synchronised time:
hwclock --systohc
Set up ntpd to automatically run and synchronise the time, as below:
chkconfig ntpd on
Now reboot the server and everything should be OK.

Just to add on a windows 2008 server use
w32tm /config /syncfromflags:manual /manualpeerlist:0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org
w32tm /config /update
w32tm /resync
to get it to check the time and
w32tm /stripchart /computer:time.windows.com /samples:3 /dataonly
to check the time