Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronise 2023.1 with upstream #106

Merged
merged 3 commits into from
Sep 16, 2024
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
10 changes: 10 additions & 0 deletions nova/tests/unit/virt/libvirt/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,16 @@ def test_driver_capabilities_secure_boot(self, mock_supports):
)
mock_supports.assert_called_once_with()

@mock.patch.object(hardware, 'get_cpu_dedicated_set',
return_value=set([0, 42, 1337]))
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_register_all_undefined_instance_details')
def test_init_host_topology(self, mock_get_cpu_dedicated_set, _):
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
with mock.patch.object(driver.cpu_api, 'power_up') as mock_power_up:
driver.init_host('goat')
mock_power_up.assert_called_with(set([0, 42, 1337]))

@mock.patch.object(
libvirt_driver.LibvirtDriver,
'_register_all_undefined_instance_details',
Expand Down
13 changes: 11 additions & 2 deletions nova/tests/unit/virt/test_virt_drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import netaddr
import os_resource_classes as orc
import os_vif
from oslo_concurrency import processutils
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import importutils
Expand Down Expand Up @@ -239,8 +240,16 @@ def test_snapshot_not_running(self):
def test_snapshot_running(self):
img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'})
instance_ref, network_info = self._get_running_instance()
self.connection.snapshot(self.ctxt, instance_ref, img_ref['id'],
lambda *args, **kwargs: None)
# this test depends on qemu-img
# being installed and in the path,
# if it is not installed, skip
try:
self.connection.snapshot(self.ctxt, instance_ref, img_ref['id'],
lambda *args, **kwargs: None)
except processutils.ProcessExecutionError as e:
if 'qemu-img' in e.stderr and 'No such file' in e.stderr:
self.skipTest("qemu-img not installed")
raise e

@catch_notimplementederror
def test_reboot(self):
Expand Down
6 changes: 3 additions & 3 deletions nova/virt/libvirt/cpu/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def core(self, i):
"""
return Core(i)

def _power_up(self, cpus: ty.Set[int]) -> None:
def power_up(self, cpus: ty.Set[int]) -> None:
if not CONF.libvirt.cpu_power_management:
return
cpu_dedicated_set = hardware.get_cpu_dedicated_set_nozero() or set()
Expand All @@ -111,7 +111,7 @@ def power_up_for_instance(self, instance: objects.Instance) -> None:
return
pcpus = instance.numa_topology.cpu_pinning.union(
instance.numa_topology.cpuset_reserved)
self._power_up(pcpus)
self.power_up(pcpus)

def power_up_for_migration(
self, dst_numa_info: objects.LibvirtLiveMigrateNUMAInfo
Expand All @@ -121,7 +121,7 @@ def power_up_for_migration(
pcpus = dst_numa_info.emulator_pins
for pins in dst_numa_info.cpu_pins.values():
pcpus = pcpus.union(pins)
self._power_up(pcpus)
self.power_up(pcpus)

def _power_down(self, cpus: ty.Set[int]) -> None:
if not CONF.libvirt.cpu_power_management:
Expand Down
23 changes: 21 additions & 2 deletions nova/virt/libvirt/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,12 +735,31 @@ def _handle_conn_event(self, enabled, reason):
{'enabled': enabled, 'reason': reason})
self._set_host_enabled(enabled, reason)

def _init_host_topology(self):
"""To work around a bug in libvirt that reports offline CPUs as always
being on socket 0 regardless of their real socket, power up all
dedicated CPUs (the only ones whose socket we actually care about),
then call get_capabilities() to initialize the topology with the
correct socket values. get_capabilities()'s implementation will reuse
these initial socket value, and avoid clobbering them with 0 for
offline CPUs.
"""
cpus = hardware.get_cpu_dedicated_set()
if cpus:
self.cpu_api.power_up(cpus)
self._host.get_capabilities()

def init_host(self, host):
self._host.initialize()

self._update_host_specific_capabilities()

# NOTE(artom) Do this first to make sure our first call to
# get_capabilities() happens with all dedicated CPUs online and caches
# their correct socket ID. Unused dedicated CPUs will be powered down
# further down in this method.
self._check_cpu_set_configuration()
self._init_host_topology()

self._update_host_specific_capabilities()

self._do_quality_warnings()

Expand Down