Skip to content

Commit

Permalink
Merge "libvirt: Allow discrete online pCPUs for pinning"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Apr 23, 2015
2 parents 49cec4c + bead2f5 commit d53ef7f
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
42 changes: 42 additions & 0 deletions nova/tests/unit/virt/libvirt/test_driver.py
Expand Up @@ -4327,6 +4327,48 @@ def test_get_all_block_devices(self, mock_list):
self.assertEqual(devices, ['/path/to/dev/1', '/path/to/dev/3'])
mock_list.assert_called_with()

@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus')
def test_get_host_vcpus(self, get_online_cpus):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.flags(vcpu_pin_set="4-5")
get_online_cpus.return_value = set([4, 5, 6])
expected_vcpus = 2
vcpus = drvr._get_vcpu_total()
self.assertEqual(expected_vcpus, vcpus)

@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus')
def test_get_host_vcpus_out_of_range(self, get_online_cpus):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.flags(vcpu_pin_set="4-6")
get_online_cpus.return_value = set([4, 5])
self.assertRaises(exception.Invalid, drvr._get_vcpu_total)

@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus')
def test_get_host_vcpus_libvirt_error(self, get_online_cpus):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
not_supported_exc = fakelibvirt.make_libvirtError(
fakelibvirt.libvirtError,
'this function is not supported by the connection driver:'
' virNodeNumOfDevices',
error_code=fakelibvirt.VIR_ERR_NO_SUPPORT)
self.flags(vcpu_pin_set="4-6")
get_online_cpus.side_effect = not_supported_exc
self.assertRaises(exception.Invalid, drvr._get_vcpu_total)

@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus')
def test_get_host_vcpus_libvirt_error_success(self, get_online_cpus):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
not_supported_exc = fakelibvirt.make_libvirtError(
fakelibvirt.libvirtError,
'this function is not supported by the connection driver:'
' virNodeNumOfDevices',
error_code=fakelibvirt.VIR_ERR_NO_SUPPORT)
self.flags(vcpu_pin_set="1")
get_online_cpus.side_effect = not_supported_exc
expected_vcpus = 1
vcpus = drvr._get_vcpu_total()
self.assertEqual(expected_vcpus, vcpus)

@mock.patch.object(host.Host, "has_min_version", return_value=True)
def test_quiesce(self, mock_has_min_version):
self.create_fake_libvirt_mock(lookupByName=self.fake_lookup)
Expand Down
20 changes: 19 additions & 1 deletion nova/virt/libvirt/driver.py
Expand Up @@ -4476,7 +4476,25 @@ def _get_vcpu_total(self):
return self._vcpu_total

available_ids = hardware.get_vcpu_pin_set()
if sorted(available_ids)[-1] >= total_pcpus:
# We get the list of online CPUs on the host and see if the requested
# set falls under these. If not, we retain the old behavior.
online_pcpus = None
try:
online_pcpus = self._host.get_online_cpus()
except libvirt.libvirtError as ex:
error_code = ex.get_error_code()
LOG.warn(_LW("Couldn't retrieve the online CPUs due to a Libvirt "
"error: %(error)s with error code: %(error_code)s"),
{'error': ex, 'error_code': error_code})
if online_pcpus:
if not (available_ids <= online_pcpus):
msg = (_("Invalid vcpu_pin_set config, one or more of the "
"specified cpuset is not online. Online cpuset(s): "
"%(online)s, requested cpuset(s): %(req)s"),
{'online': sorted(online_pcpus),
'req': sorted(available_ids)})
raise exception.Invalid(msg)
elif sorted(available_ids)[-1] >= total_pcpus:
raise exception.Invalid(_("Invalid vcpu_pin_set config, "
"out of hypervisor cpu range."))
self._vcpu_total = len(available_ids)
Expand Down

0 comments on commit d53ef7f

Please sign in to comment.