Skip to content

Commit b065974

Browse files
cbf123stephenfin
authored andcommitted
hardware: Add validation for 'cpu_realtime_mask'
It's possible to specify some strange values for the cpu realtime mask and the code won't currently complain, so let's make it a bit more strict. Change-Id: I0ba06529affe5b48af5ac37bc24242dffdac77d3 Closes-Bug: #1884231
1 parent 6a71981 commit b065974

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

nova/tests/unit/virt/test_hardware.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3658,14 +3658,53 @@ def test_no_mask_configured(self):
36583658
exception.RealtimeMaskNotFoundOrInvalid,
36593659
hw.vcpus_realtime_topology, flavor, image)
36603660

3661-
def test_mask_badly_configured(self):
3661+
def test_invalid_mask_no_rt_cpus(self):
3662+
# The mask excludes all vCPUs from being RT
36623663
flavor = objects.Flavor(vcpus=3, memory_mb=2048,
36633664
extra_specs={"hw:cpu_realtime_mask": "^0-2"})
36643665
image = objects.ImageMeta.from_dict({"properties": {}})
36653666
self.assertRaises(
36663667
exception.RealtimeMaskNotFoundOrInvalid,
36673668
hw.vcpus_realtime_topology, flavor, image)
36683669

3670+
def test_invalid_mask_exclude_out_of_range(self):
3671+
# The mask excludes an invalidly high vCPU number.
3672+
flavor = objects.Flavor(vcpus=3, memory_mb=2048,
3673+
extra_specs={"hw:cpu_realtime_mask": "^3"})
3674+
image = objects.ImageMeta.from_dict({"properties": {}})
3675+
self.assertRaises(
3676+
exception.RealtimeMaskNotFoundOrInvalid,
3677+
hw.vcpus_realtime_topology, flavor, image)
3678+
3679+
def test_explicit_range(self):
3680+
# The mask is not just an exclusion mask. This is unexpected but
3681+
# the code doesn't prevent it.
3682+
flavor = objects.Flavor(vcpus=3, memory_mb=2048,
3683+
extra_specs={"hw:cpu_realtime_mask": "0-2,^0"})
3684+
image = objects.ImageMeta.from_dict({"properties": {}})
3685+
rt = hw.vcpus_realtime_topology(flavor, image)
3686+
self.assertEqual({1, 2}, rt)
3687+
3688+
def test_invalid_mask_no_exclusion_wo_emulator_policy(self):
3689+
# The mask has no exclusion and there's no emulator thread policy
3690+
# configured
3691+
flavor = objects.Flavor(vcpus=3, memory_mb=2048,
3692+
extra_specs={"hw:cpu_realtime_mask": "0-2"})
3693+
image = objects.ImageMeta.from_dict({"properties": {}})
3694+
self.assertRaises(
3695+
exception.RealtimeMaskNotFoundOrInvalid,
3696+
hw.vcpus_realtime_topology, flavor, image)
3697+
3698+
def test_invalid_mask_rt_cpus_out_of_range(self):
3699+
# The mask is not just an exclusion mask, and the RT range specifies
3700+
# an invalid vCPU number.
3701+
flavor = objects.Flavor(vcpus=3, memory_mb=2048,
3702+
extra_specs={"hw:cpu_realtime_mask": "0-3,^0"})
3703+
image = objects.ImageMeta.from_dict({"properties": {}})
3704+
self.assertRaises(
3705+
exception.RealtimeMaskNotFoundOrInvalid,
3706+
hw.vcpus_realtime_topology, flavor, image)
3707+
36693708

36703709
class EmulatorThreadsTestCase(test.NoDBTestCase):
36713710

nova/virt/hardware.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1720,10 +1720,21 @@ def vcpus_realtime_topology(
17201720
if not mask:
17211721
raise exception.RealtimeMaskNotFoundOrInvalid()
17221722

1723+
vcpus_set = set(range(flavor.vcpus))
17231724
vcpus_rt = parse_cpu_spec("0-%d,%s" % (flavor.vcpus - 1, mask))
1724-
if len(vcpus_rt) < 1:
1725+
1726+
if not vcpus_rt:
1727+
raise exception.RealtimeMaskNotFoundOrInvalid()
1728+
1729+
if vcpus_set == vcpus_rt:
17251730
raise exception.RealtimeMaskNotFoundOrInvalid()
17261731

1732+
if not vcpus_rt.issubset(vcpus_set):
1733+
msg = _("Realtime policy vCPU(s) mask is configured with RT vCPUs "
1734+
"that are not a subset of the vCPUs in the flavor. See "
1735+
"hw:cpu_realtime_mask or hw_cpu_realtime_mask")
1736+
raise exception.RealtimeMaskNotFoundOrInvalid(msg)
1737+
17271738
return vcpus_rt
17281739

17291740

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
Previously, it was possible to specify values for the
5+
``hw:cpu_realtime_mask`` extra spec that were not within the range of valid
6+
instances cores. This value is now correctly validated.

0 commit comments

Comments
 (0)