return_value='fake_pci_devs'),
mock.patch.object(utils, 'get_image_from_system_metadata'),
mock.patch.object(blockinfo, 'get_disk_info'),
+ mock.patch.object(guest, 'sync_guest_time'),
+ mock.patch.object(drvr, '_wait_for_running',
+ side_effect=loopingcall.LoopingCallDone()),
) as (_get_existing_domain_xml, _create_domain_and_network,
_attach_pci_devices, get_instance_pci_devs, get_image_metadata,
- get_disk_info):
+ get_disk_info, mock_sync_time, mock_wait):
get_image_metadata.return_value = {'bar': 234}
disk_info = {'foo': 123}
instance, network_info, disk_info,
block_device_info=block_device_info,
vifs_already_plugged=True)])
+ self.assertTrue(mock_sync_time.called)
_attach_pci_devices.assert_has_calls([mock.call(guest,
'fake_pci_devs')])
self.fake_create_domain_called = True
self.assertEqual(powered_on, power_on)
self.assertTrue(vifs_already_plugged)
+ return libvirt_guest.Guest('fake_dom')
def fake_enable_hairpin():
pass
resize_instance, self.fake_disk_resize_called)
def test_finish_migration_resize(self):
- self._test_finish_migration(True, resize_instance=True)
+ with mock.patch('nova.virt.libvirt.guest.Guest.sync_guest_time'
+ ) as mock_guest_time:
+ self._test_finish_migration(True, resize_instance=True)
+ self.assertTrue(mock_guest_time.called)
def test_finish_migration_power_on(self):
- self._test_finish_migration(True)
+ with mock.patch('nova.virt.libvirt.guest.Guest.sync_guest_time'
+ ) as mock_guest_time:
+ self._test_finish_migration(True)
+ self.assertTrue(mock_guest_time.called)
def test_finish_migration_power_off(self):
self._test_finish_migration(False)
@mock.patch('time.time', return_value=1234567890.125)
def test_time_sync_no_errors(self, time_mock):
self.domain.setTime.side_effect = fakelibvirt.libvirtError('error')
- self.guest.resume()
+ self.guest.sync_guest_time()
self.domain.setTime.assert_called_once_with(time={
'nseconds': 125000000,
'seconds': 1234567890})
def unpause(self, instance):
"""Unpause paused VM instance."""
- self._host.get_guest(instance).resume()
+ guest = self._host.get_guest(instance)
+ guest.resume()
+ guest.sync_guest_time()
def _clean_shutdown(self, instance, timeout, retry_interval):
"""Attempt to shutdown the instance gracefully.
self._attach_pci_devices(guest,
pci_manager.get_instance_pci_devs(instance))
self._attach_sriov_ports(context, instance, guest, network_info)
+ timer = loopingcall.FixedIntervalLoopingCall(self._wait_for_running,
+ instance)
+ timer.start(interval=0.5).wait()
+ guest.sync_guest_time()
def resume_state_on_host_boot(self, context, instance, network_info,
block_device_info=None):
# and the status change in the port might go undetected by the neutron
# L2 agent (or neutron server) so neutron may not know that the VIF was
# unplugged in the first place and never send an event.
- self._create_domain_and_network(context, xml, instance, network_info,
+ guest = self._create_domain_and_network(context, xml, instance,
+ network_info,
block_disk_info,
block_device_info=block_device_info,
power_on=power_on,
instance)
timer.start(interval=0.5).wait()
+ # Sync guest time after migration.
+ guest.sync_guest_time()
+
LOG.debug("finish_migration finished successfully.", instance=instance)
def _cleanup_failed_migration(self, inst_base):
"""Stops a running guest."""
self._domain.destroy()
- def _sync_guest_time(self):
+ def sync_guest_time(self):
"""Try to set VM time to the current value. This is typically useful
when clock wasn't running on the VM for some time (e.g. during
suspension or migration), especially if the time delay exceeds NTP
self._domain.injectNMI()
def resume(self):
- """Resumes a suspended guest."""
+ """Resumes a paused guest."""
self._domain.resume()
- self._sync_guest_time()
def enable_hairpin(self):
"""Enables hairpin mode for this guest."""