Merge "Add handling for offlined CPUs to the nova libvirt driver."

This commit is contained in:
Jenkins 2015-02-18 14:50:15 +00:00 committed by Gerrit Code Review
commit 7885332a11
4 changed files with 53 additions and 9 deletions

View File

@ -827,6 +827,10 @@ class Connection(object):
def registerCloseCallback(self, cb, opaque): def registerCloseCallback(self, cb, opaque):
pass pass
def getCPUMap(self):
"""Return spoofed CPU map, showing 2 online CPUs."""
return (2, [True] * 2, 2)
def getCapabilities(self): def getCapabilities(self):
"""Return spoofed capabilities.""" """Return spoofed capabilities."""
return '''<capabilities> return '''<capabilities>

View File

@ -1234,7 +1234,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock.patch.object( mock.patch.object(
random, 'choice', side_effect=lambda cells: cells[0]), random, 'choice', side_effect=lambda cells: cells[0]),
mock.patch.object(pci_manager, "get_instance_pci_devs", mock.patch.object(pci_manager, "get_instance_pci_devs",
return_value=[pci_device])): return_value=[pci_device]),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8)))):
cfg = conn._get_guest_config(instance_ref, [], {}, disk_info) cfg = conn._get_guest_config(instance_ref, [], {}, disk_info)
self.assertIsNone(instance_ref.numa_topology) self.assertIsNone(instance_ref.numa_topology)
self.assertEqual(set([2, 3]), cfg.cpuset) self.assertEqual(set([2, 3]), cfg.cpuset)
@ -1279,6 +1281,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
host.Host, "get_capabilities", return_value=caps), host.Host, "get_capabilities", return_value=caps),
mock.patch.object( mock.patch.object(
hardware, 'get_vcpu_pin_set', return_value=set([3])), hardware, 'get_vcpu_pin_set', return_value=set([3])),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8))),
mock.patch.object(pci_manager, "get_instance_pci_devs", mock.patch.object(pci_manager, "get_instance_pci_devs",
return_value=[pci_device])): return_value=[pci_device])):
cfg = conn._get_guest_config(instance_ref, [], {}, disk_info) cfg = conn._get_guest_config(instance_ref, [], {}, disk_info)
@ -1402,9 +1406,12 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock.patch.object( mock.patch.object(
hardware, 'get_vcpu_pin_set', return_value=set([2, 3])), hardware, 'get_vcpu_pin_set', return_value=set([2, 3])),
mock.patch.object( mock.patch.object(
random, 'choice', side_effect=lambda cells: cells[0]) random, 'choice', side_effect=lambda cells: cells[0]),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8)))
) as (has_min_version_mock, get_host_cap_mock, ) as (has_min_version_mock, get_host_cap_mock,
get_vcpu_pin_set_mock, choice_mock): get_vcpu_pin_set_mock, choice_mock,
get_online_cpus_mock):
cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info) cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info)
# NOTE(ndipanov): we make sure that pin_set was taken into account # NOTE(ndipanov): we make sure that pin_set was taken into account
# when choosing viable cells # when choosing viable cells
@ -1498,7 +1505,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
return_value=caps), return_value=caps),
mock.patch.object( mock.patch.object(
hardware, 'get_vcpu_pin_set', hardware, 'get_vcpu_pin_set',
return_value=set([2, 3, 4, 5])) return_value=set([2, 3, 4, 5])),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8))),
): ):
cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info) cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info)
self.assertIsNone(cfg.cpuset) self.assertIsNone(cfg.cpuset)
@ -1575,6 +1584,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
return_value=True), return_value=True),
mock.patch.object(host.Host, "get_capabilities", mock.patch.object(host.Host, "get_capabilities",
return_value=caps), return_value=caps),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8))),
): ):
cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info) cfg = drvr._get_guest_config(instance_ref, [], {}, disk_info)
self.assertIsNone(cfg.cpuset) self.assertIsNone(cfg.cpuset)
@ -1649,7 +1660,9 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock.patch.object(host.Host, 'has_min_version', mock.patch.object(host.Host, 'has_min_version',
return_value=True), return_value=True),
mock.patch.object(host.Host, "get_capabilities", mock.patch.object(host.Host, "get_capabilities",
return_value=caps) return_value=caps),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set(range(8))),
): ):
cfg = conn._get_guest_config(instance_ref, [], {}, disk_info) cfg = conn._get_guest_config(instance_ref, [], {}, disk_info)
self.assertIsNone(cfg.cpuset) self.assertIsNone(cfg.cpuset)
@ -9623,7 +9636,10 @@ class LibvirtConnTestCase(test.NoDBTestCase):
mock.patch.object(host.Host, "get_capabilities", mock.patch.object(host.Host, "get_capabilities",
return_value=caps), return_value=caps),
mock.patch.object( mock.patch.object(
hardware, 'get_vcpu_pin_set', return_value=set([0, 1, 3])) hardware, 'get_vcpu_pin_set',
return_value=set([0, 1, 3, 4, 5])),
mock.patch.object(host.Host, 'get_online_cpus',
return_value=set([0, 1, 2, 3, 6])),
): ):
got_topo = drvr._get_host_numa_topology() got_topo = drvr._get_host_numa_topology()
got_topo_dict = got_topo._to_dict() got_topo_dict = got_topo._to_dict()

View File

@ -4748,6 +4748,11 @@ class LibvirtDriver(driver.ComputeDriver):
cells = [] cells = []
allowed_cpus = hardware.get_vcpu_pin_set() allowed_cpus = hardware.get_vcpu_pin_set()
online_cpus = self._host.get_online_cpus()
if allowed_cpus:
allowed_cpus &= online_cpus
else:
allowed_cpus = online_cpus
for cell in topology.cells: for cell in topology.cells:
cpuset = set(cpu.id for cpu in cell.cpus) cpuset = set(cpu.id for cpu in cell.cpus)
@ -4756,9 +4761,8 @@ class LibvirtDriver(driver.ComputeDriver):
if cpu.siblings else () if cpu.siblings else ()
for cpu in cell.cpus) for cpu in cell.cpus)
)) ))
if allowed_cpus: cpuset &= allowed_cpus
cpuset &= allowed_cpus siblings = [sib & allowed_cpus for sib in siblings]
siblings = [sib & allowed_cpus for sib in siblings]
# Filter out singles and empty sibling sets that may be left # Filter out singles and empty sibling sets that may be left
siblings = [sib for sib in siblings if len(sib) > 1] siblings = [sib for sib in siblings if len(sib) > 1]

View File

@ -585,6 +585,26 @@ class Host(object):
return doms return doms
def get_online_cpus(self):
"""Get the set of CPUs that are online on the host
Method is only used by NUMA code paths which check on
libvirt version >= 1.0.4. getCPUMap() was introduced in
libvirt 1.0.0.
:returns: set of online CPUs, raises libvirtError on error
"""
(cpus, cpu_map, online) = self.get_connection().getCPUMap()
online_cpus = set()
for cpu in range(cpus):
if cpu_map[cpu]:
online_cpus.add(cpu)
return online_cpus
def get_capabilities(self): def get_capabilities(self):
"""Returns the host capabilities information """Returns the host capabilities information