Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions doc/source/admin/scheduling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1122,10 +1122,9 @@ scheduling.
Usage scenarios
~~~~~~~~~~~~~~~

Since allocation ratios can be set via nova configuration, host aggregate
metadata and the placement API, it can be confusing to know which should be
used. This really depends on your scenario. A few common scenarios are detailed
here.
Since allocation ratios can be set via nova configuration and the placement
API, it can be confusing to know which should be used. This really depends on
your scenario. A few common scenarios are detailed here.

1. When the deployer wants to **always** set an override value for a resource
on a compute node, the deployer should ensure that the
Expand Down
33 changes: 30 additions & 3 deletions nova/tests/unit/virt/libvirt/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ def _create_test_instance():
'numa_topology': None,
'config_drive': None,
'vm_mode': None,
'vm_state': None,
'kernel_id': None,
'ramdisk_id': None,
'os_type': 'linux',
Expand Down Expand Up @@ -12313,7 +12314,7 @@ def test_live_migration_update_volume_xml(self, mock_xml,
mock_updated_guest_xml,
mock_migrateToURI3):
self.compute = manager.ComputeManager()
instance_ref = self.test_instance
instance_ref = objects.Instance(**self.test_instance)
target_connection = '127.0.0.2'

target_xml = self.device_xml_tmpl.format(
Expand Down Expand Up @@ -12482,7 +12483,7 @@ def test_live_migration_with_valid_target_connect_addr(self, mock_xml,
mock_migrateToURI3,
mock_min_version):
self.compute = manager.ComputeManager()
instance_ref = self.test_instance
instance_ref = objects.Instance(**self.test_instance)
target_connection = '127.0.0.2'

target_xml = self.device_xml_tmpl.format(
Expand Down Expand Up @@ -13097,6 +13098,33 @@ def test_block_live_migration_tunnelled_migrateToURI3(
drvr._live_migration_uri(target_connection),
params=params, flags=expected_flags)

@mock.patch.object(host.Host, 'has_min_version', return_value=True)
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI3")
@mock.patch('nova.virt.libvirt.migration.get_updated_guest_xml',
return_value='')
def test_live_migration_paused_instance_postcopy(self, mock_new_xml,
mock_migrateToURI3,
mock_min_version):
disk_paths = []
params = {'bandwidth': CONF.libvirt.live_migration_bandwidth}
migrate_data = objects.LibvirtLiveMigrateData(block_migration=False,
serial_listen_addr=False)
dom = fakelibvirt.virDomain
guest = libvirt_guest.Guest(dom)
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
drvr._parse_migration_flags()
instance = objects.Instance(**self.test_instance)
instance.vm_state = vm_states.PAUSED

drvr._live_migration_operation(self.context, instance, 'dest',
True, migrate_data, guest,
disk_paths)

# Verify VIR_MIGRATE_POSTCOPY flag was not set
self.assertEqual(drvr._live_migration_flags, 27)
mock_migrateToURI3.assert_called_once_with(
drvr._live_migration_uri('dest'), params=params, flags=27)

@mock.patch.object(host.Host, 'has_min_version', return_value=True)
@mock.patch.object(fakelibvirt.virDomain, "migrateToURI3")
@mock.patch('nova.virt.libvirt.migration.get_updated_guest_xml',
Expand All @@ -13106,7 +13134,6 @@ def test_block_live_migration_native_tls(
self, mock_old_xml, mock_new_xml,
mock_migrateToURI3, mock_min_version):
self.flags(live_migration_with_native_tls=True, group='libvirt')

target_connection = None
disk_paths = ['vda', 'vdb']

Expand Down
10 changes: 9 additions & 1 deletion nova/tests/unit/virt/libvirt/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,10 @@ def test_get_machine_type_from_image(self):
os_mach_type = libvirt_utils.get_machine_type(image_meta)
self.assertEqual('q35', os_mach_type)

def test_make_reverse_cpu_traits_mapping(self):
for k in libvirt_utils.make_reverse_cpu_traits_mapping():
self.assertIsInstance(k, str)

def test_get_flags_by_flavor_specs(self):
flavor = objects.Flavor(
id=1, flavorid='fakeid-1', name='fake1.small', memory_mb=128,
Expand All @@ -718,11 +722,15 @@ def test_get_flags_by_flavor_specs(self):
'trait:%s' % os_traits.HW_CPU_X86_3DNOW: 'required',
'trait:%s' % os_traits.HW_CPU_X86_SSE2: 'required',
'trait:%s' % os_traits.HW_CPU_HYPERTHREADING: 'required',
'trait:%s' % os_traits.HW_CPU_X86_INTEL_VMX: 'required',
'trait:%s' % os_traits.HW_CPU_X86_VMX: 'required',
'trait:%s' % os_traits.HW_CPU_X86_SVM: 'required',
'trait:%s' % os_traits.HW_CPU_X86_AMD_SVM: 'required',
})
traits = libvirt_utils.get_flags_by_flavor_specs(flavor)
# we shouldn't see the hyperthreading trait since that's a valid trait
# but not a CPU flag
self.assertEqual(set(['3dnow', 'sse2']), traits)
self.assertEqual(set(['3dnow', 'sse2', 'vmx', 'svm']), traits)

@mock.patch('nova.virt.libvirt.utils.copy_image')
@mock.patch('nova.privsep.path.chown')
Expand Down
11 changes: 11 additions & 0 deletions nova/virt/libvirt/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -10152,6 +10152,17 @@ def _live_migration_operation(self, context, instance, dest,
else:
migration_flags = self._live_migration_flags

# Note(siva_krishnan): live migrating paused instance fails
# when VIR_MIGRATE_POSTCOPY flag is set. It is unset here
# to permit live migration of paused instance.
if (
instance.vm_state == vm_states.PAUSED and
self._is_post_copy_enabled(migration_flags)
):
LOG.debug('Post-copy flag unset because instance is paused.',
instance=instance)
migration_flags ^= libvirt.VIR_MIGRATE_POSTCOPY

if not migrate_data.serial_listen_addr:
# In this context we want to ensure that serial console is
# disabled on source node. This is because nova couldn't
Expand Down
14 changes: 13 additions & 1 deletion nova/virt/libvirt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,20 @@
'xop': os_traits.HW_CPU_X86_XOP
}


def make_reverse_cpu_traits_mapping() -> ty.Dict[str, str]:
traits_cpu_mapping = dict()
for k, v in CPU_TRAITS_MAPPING.items():
if isinstance(v, tuple):
for trait in v:
traits_cpu_mapping[trait] = k
else:
traits_cpu_mapping[v] = k
return traits_cpu_mapping


# Reverse CPU_TRAITS_MAPPING
TRAITS_CPU_MAPPING = {v: k for k, v in CPU_TRAITS_MAPPING.items()}
TRAITS_CPU_MAPPING = make_reverse_cpu_traits_mapping()

# global directory for emulated TPM
VTPM_DIR = '/var/lib/libvirt/swtpm/'
Expand Down