From 3114a97ba188895daff4a3d337b2c73855d4632d Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 11 Jun 2012 17:16:10 +0100 Subject: Update default policies for KVM guest PIT & RTC timers The default policies for the KVM guest PIT and RTC timers are not very good at maintaining reliable time in guest operating systems. In particular Windows 7 guests will often crash with the default KVM timer policies, and old Linux guests will have very bad time drift Set the PIT such that missed ticks are injected at the normal rate, ie they are delayed Set the RTC such that missed ticks are injected at a higher rate to "catch up" This corresponds to the following libvirt XML And the following KVM options -no-kvm-pit-reinjection -rtc base=utc,driftfix=slew This should provide a default configuration that works acceptably for most OS types. In the future this will likely need to be made configurable per-guest OS type. Fixes LP bug #1011848 Change-Id: Iafb0e2192b5f3c05b6395ffdfa14f86a98ce3d1f Signed-off-by: Daniel P. Berrange --- nova/tests/test_libvirt.py | 15 +++++++++++++++ nova/virt/libvirt/connection.py | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index a0ef00605..6e6604e35 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -526,6 +526,21 @@ class LibvirtConnTestCase(test.TestCase): self.assertEquals(type(cfg.devices[6]), config.LibvirtConfigGuestGraphics) + self.assertEquals(type(cfg.clock), + config.LibvirtConfigGuestClock) + self.assertEquals(cfg.clock.offset, "utc") + self.assertEquals(len(cfg.clock.timers), 2) + self.assertEquals(type(cfg.clock.timers[0]), + config.LibvirtConfigGuestTimer) + self.assertEquals(type(cfg.clock.timers[1]), + config.LibvirtConfigGuestTimer) + self.assertEquals(cfg.clock.timers[0].name, "pit") + self.assertEquals(cfg.clock.timers[0].tickpolicy, + "delay") + self.assertEquals(cfg.clock.timers[1].name, "rtc") + self.assertEquals(cfg.clock.timers[1].tickpolicy, + "catchup") + def test_get_guest_config_with_two_nics(self): conn = connection.LibvirtDriver(True) instance_ref = db.instance_create(self.context, self.test_instance) diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index fe117159b..12cd3f429 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -1503,6 +1503,24 @@ class LibvirtDriver(driver.ComputeDriver): if FLAGS.libvirt_type != "lxc" and FLAGS.libvirt_type != "uml": guest.acpi = True + clk = config.LibvirtConfigGuestClock() + clk.offset = "utc" + guest.set_clock(clk) + + if FLAGS.libvirt_type == "kvm": + # TODO(berrange) One day this should be per-guest + # OS type configurable + tmpit = config.LibvirtConfigGuestTimer() + tmpit.name = "pit" + tmpit.tickpolicy = "delay" + + tmrtc = config.LibvirtConfigGuestTimer() + tmrtc.name = "rtc" + tmrtc.tickpolicy = "catchup" + + clk.add_timer(tmpit) + clk.add_timer(tmrtc) + if FLAGS.libvirt_type == "lxc": fs = config.LibvirtConfigGuestFilesys() fs.type = "mount" -- cgit