Merge "Check if destination can support the src mdev types"
This commit is contained in:
commit
bdd7daffbb
@ -8539,6 +8539,10 @@ class ComputeManager(manager.Manager):
|
||||
# Update migrate VIFs with the newly claimed PCI devices
|
||||
self._update_migrate_vifs_profile_with_pci(
|
||||
migrate_data.vifs, port_id_to_pci)
|
||||
# This should always be the last check as we persist some internal
|
||||
# dictionary value in the libvirt driver.
|
||||
migrate_data = self.driver.check_source_migrate_data_at_dest(
|
||||
ctxt, instance, migrate_data, migration, limits, allocs)
|
||||
finally:
|
||||
self.driver.cleanup_live_migration_destination_check(ctxt,
|
||||
dest_check_data)
|
||||
|
@ -540,6 +540,34 @@ class VGPULiveMigrationTests(base.LibvirtMigrationMixin, VGPUTestBase):
|
||||
'' % server['id'],
|
||||
log_out)
|
||||
|
||||
def test_live_migration_fails_due_to_non_supported_mdev_types(self):
|
||||
self.flags(
|
||||
enabled_mdev_types=[fakelibvirt.NVIDIA_11_VGPU_TYPE],
|
||||
group='devices')
|
||||
self.src = self.restart_compute_service(self.src.host)
|
||||
self.flags(
|
||||
enabled_mdev_types=[fakelibvirt.NVIDIA_12_VGPU_TYPE],
|
||||
group='devices')
|
||||
self.dest = self.restart_compute_service(self.dest.host)
|
||||
# Force a periodic run in order to make sure all service resources
|
||||
# are changed before we call create_service()
|
||||
self._run_periodics()
|
||||
self.server = self._create_server(
|
||||
image_uuid='155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
flavor_id=self.flavor, networks='auto', host=self.src.host)
|
||||
# now live migrate that server
|
||||
ex = self.assertRaises(
|
||||
client.OpenStackApiException,
|
||||
self._live_migrate,
|
||||
self.server, 'completed')
|
||||
self.assertEqual(500, ex.response.status_code)
|
||||
self.assertIn('NoValidHost', str(ex))
|
||||
log_out = self.stdlog.logger.output
|
||||
# The log is fully JSON-serialized, so just check the phrase.
|
||||
self.assertIn('Unable to migrate %s: ' % self.server['id'], log_out)
|
||||
self.assertIn('Source mdev types ', log_out)
|
||||
self.assertIn('are not supported by this compute : ', log_out)
|
||||
|
||||
def test_live_migrate_server(self):
|
||||
self.server = self._create_server(
|
||||
image_uuid='155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
|
@ -3576,10 +3576,13 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
'_update_migrate_vifs_profile_with_pci'),
|
||||
mock.patch.object(self.compute, '_dest_can_numa_live_migrate'),
|
||||
mock.patch('nova.compute.manager.LOG'),
|
||||
mock.patch.object(self.compute.driver,
|
||||
'check_source_migrate_data_at_dest'),
|
||||
) as (mock_lm_claim, mock_get, mock_check_dest, mock_check_src,
|
||||
mock_check_clean, mock_fault_create, mock_event,
|
||||
mock_create_mig_vif, mock_nw_info, mock_claim_pci,
|
||||
mock_update_mig_vif, mock_dest_can_numa, mock_log):
|
||||
mock_update_mig_vif, mock_dest_can_numa, mock_log,
|
||||
mock_post_check):
|
||||
mock_get.side_effect = (src_info, dest_info)
|
||||
mock_check_dest.return_value = dest_check_data
|
||||
mock_dest_can_numa.return_value = dest_check_data
|
||||
@ -3587,6 +3590,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
dst_numa_info=objects.LibvirtLiveMigrateNUMAInfo())
|
||||
mock_lm_claim.return_value = post_claim_md
|
||||
|
||||
# In the case of a NUMA related claim, migrate_data is updated
|
||||
post_claim_mig_data = post_claim_md if src_numa_lm else mig_data
|
||||
mock_post_check.return_value = post_claim_mig_data
|
||||
|
||||
if do_raise:
|
||||
mock_check_src.side_effect = test.TestingException
|
||||
mock_fault_create.return_value = \
|
||||
@ -3631,6 +3638,9 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
mock_event.assert_called_once_with(
|
||||
self.context, 'compute_check_can_live_migrate_destination',
|
||||
CONF.host, instance.uuid, graceful_exit=False)
|
||||
mock_post_check.assert_called_once_with(
|
||||
self.context, instance, post_claim_mig_data, migration, limits,
|
||||
None)
|
||||
return result
|
||||
|
||||
@mock.patch('nova.objects.InstanceGroup.get_by_instance_uuid', mock.Mock(
|
||||
|
@ -11699,6 +11699,43 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
for vif in result.vifs:
|
||||
self.assertTrue(vif.supports_os_vif_delegation)
|
||||
|
||||
def test_check_source_migrate_data_at_dest_no_src_mdevs(self):
|
||||
"""Noop test in case no mdevs from the source."""
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
dest_check_data = objects.LibvirtLiveMigrateData(
|
||||
filename="file",
|
||||
block_migration=True,
|
||||
disk_over_commit=False,
|
||||
disk_available_mb=1024)
|
||||
allocations = {uuids.rp1: {'resources': {orc.VGPU: 1}}}
|
||||
result = drvr.check_source_migrate_data_at_dest(
|
||||
self.context, instance_ref, dest_check_data, None, None,
|
||||
allocations)
|
||||
self.assertEqual(dest_check_data, result)
|
||||
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver,
|
||||
'_get_supported_vgpu_types')
|
||||
def test_check_source_migrate_data_at_dest_types_not_supported(self,
|
||||
mock_get):
|
||||
"""Raises an exception if the destination doesn't support the source
|
||||
mdev types.
|
||||
"""
|
||||
mock_get.return_value = ['type1']
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
dest_check_data = objects.LibvirtLiveMigrateData(
|
||||
filename="file",
|
||||
block_migration=True,
|
||||
disk_over_commit=False,
|
||||
disk_available_mb=1024,
|
||||
source_mdev_types={uuids.mdev1: 'wrongtype'})
|
||||
allocations = {uuids.rp1: {'resources': {orc.VGPU: 1}}}
|
||||
self.assertRaises(exception.MigrationPreCheckError,
|
||||
drvr.check_source_migrate_data_at_dest,
|
||||
self.context, instance_ref, dest_check_data,
|
||||
None, None, allocations)
|
||||
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion')
|
||||
@mock.patch.object(fakelibvirt.Connection, 'getVersion')
|
||||
def _test_host_can_support_mdev_lm(self, mock_getversion,
|
||||
|
@ -1312,6 +1312,22 @@ class ComputeDriver(object):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def check_source_migrate_data_at_dest(self, ctxt, instance, migrate_data,
|
||||
migration, limits, allocs):
|
||||
"""Runs the last checks on the destination after the source returned
|
||||
the migrate_data.
|
||||
|
||||
:param ctxt: security context
|
||||
:param instance: nova.db.main.models.Instance
|
||||
:param migrate_data: result of check_can_live_migrate_source
|
||||
:param migration: The Migration object for this live migration
|
||||
:param limits: The SchedulerLimits object for this live migration
|
||||
:param allocs: Allocations for this instance
|
||||
:returns: a LibvirtLiveMigrateData object
|
||||
:raises: MigrationPreCheckError
|
||||
"""
|
||||
return migrate_data
|
||||
|
||||
def post_claim_migrate_data(self, context, instance, migrate_data, claim):
|
||||
"""Returns migrate_data augmented with any information obtained from
|
||||
the claim. Intended to run on the destination of a live-migration
|
||||
|
@ -9769,6 +9769,37 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
|
||||
return data
|
||||
|
||||
def check_source_migrate_data_at_dest(self, ctxt, instance, migrate_data,
|
||||
migration, limits, allocs):
|
||||
"""Runs the last checks on the destination after the source returned
|
||||
the migrate_data.
|
||||
|
||||
:param ctxt: security context
|
||||
:param instance: nova.db.main.models.Instance
|
||||
:param migrate_data: result of check_can_live_migrate_source
|
||||
:param migration: The Migration object for this live migration
|
||||
:param limits: The SchedulerLimits object for this live migration
|
||||
:param allocs: Allocations for this instance
|
||||
:returns: a LibvirtLiveMigrateData object
|
||||
:raises: MigrationPreCheckError
|
||||
"""
|
||||
if ('source_mdev_types' in migrate_data and
|
||||
migrate_data.source_mdev_types):
|
||||
# The instance that needs to be live-migrated has some mdevs
|
||||
src_mdev_types = migrate_data.source_mdev_types
|
||||
# As a reminder, src_mdev_types is a dict of mdev UUID and its type
|
||||
# Are all the types supported by this compute ?
|
||||
if not all(map(lambda m_type: m_type in self.supported_vgpu_types,
|
||||
src_mdev_types.values())):
|
||||
reason = (_('Unable to migrate %(instance_uuid)s: '
|
||||
'Source mdev types %(src_types)s are not '
|
||||
'supported by this compute : %(dest_types)s ' %
|
||||
{'instance_uuid': instance.uuid,
|
||||
'src_types': list(src_mdev_types.values()),
|
||||
'dest_types': self.supported_vgpu_types}))
|
||||
raise exception.MigrationPreCheckError(reason)
|
||||
return migrate_data
|
||||
|
||||
def post_claim_migrate_data(self, context, instance, migrate_data, claim):
|
||||
migrate_data.dst_numa_info = self._get_live_migrate_numa_info(
|
||||
claim.claimed_numa_topology, claim.flavor, claim.image_meta)
|
||||
|
Loading…
Reference in New Issue
Block a user