Skip to content

Commit d907c1f

Browse files
committed
Reproduce bug/2097359
In Victoria InstanceNUMACell ovo got the new pcpuset field and a connected in place data migration. If the cpu_policy is dedicated the content of the cpuset is moved to to the new pcpuset field during the load of the data from the DB and the ovo is persisted back to the DB. However during this data migration the version of the ovo is not bumped to the latest, 1.6, version. Therefore the DB contains an inconsistent object as it has the new pcpuset field from 1.6 but the nova_object.version is still set to 1.4. It turned out that this can cause that an old compute node having ovo 1.4 code will not request a back levelling of the ovo even if it is already data migrated to 1.6 causing data loss from the compute perspective. Also if the compute saves the object back to DB then the data loss becomes persistent. Related-Bug: #2097359 Change-Id: I76ee9d59abc39e29c54be7217491e911b88a0621 (cherry picked from commit ae2f9bd) (cherry picked from commit 82b5bd6) (cherry picked from commit a3d3b89) (cherry picked from commit db9a810)
1 parent 4c9267c commit d907c1f

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

nova/tests/unit/objects/test_instance_numa.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import copy
1414
from unittest import mock
1515

16+
from oslo_serialization import jsonutils
1617
from oslo_utils.fixture import uuidsentinel as uuids
1718
from oslo_versionedobjects import base as ovo_base
1819
import testtools
@@ -411,6 +412,46 @@ def test_obj_from_db_obj_no_pinning(self):
411412
self.assertEqual(topo_cell.cpuset, obj_cell.cpuset)
412413
self.assertEqual(set(), obj_cell.pcpuset)
413414

415+
def test__migrate_legacy_dedicated_instance_cpuset(self):
416+
# Create a topology with a cell on latest version. Would be nice
417+
# to create one the old 1.4 cell version directly but that is only
418+
# possible indirectly as done below.
419+
topo = objects.InstanceNUMATopology(
420+
instance_uuid=fake_instance_uuid,
421+
cells=[
422+
objects.InstanceNUMACell(id=0, cpuset=set(), pcpuset={0, 1}),
423+
])
424+
topo.cells[0].cpu_policy = objects.fields.CPUAllocationPolicy.DEDICATED
425+
426+
# Use the builtin backlevelling logic to pull it back to old cell
427+
# version
428+
topo_with_cell_1_4 = topo.obj_to_primitive(
429+
target_version='1.3', version_manifest={'InstanceNUMACell': '1.4'})
430+
431+
# Just check that the backlevelling works, and we have a cell with
432+
# version and data on 1.4 level
433+
cell_1_4_primitive = topo_with_cell_1_4['nova_object.data']['cells'][0]
434+
self.assertEqual('1.4', cell_1_4_primitive['nova_object.version'])
435+
self.assertEqual(
436+
(0, 1), cell_1_4_primitive['nova_object.data']['cpuset'])
437+
self.assertNotIn('pcpuset', cell_1_4_primitive['nova_object.data'])
438+
439+
# Now simulate that such old data is loaded from the DB and migrated
440+
# from 1.4 to 1.6 by the data migration
441+
topo_loaded = objects.InstanceNUMATopology.obj_from_db_obj(
442+
self.context, fake_instance_uuid,
443+
jsonutils.dumps(topo_with_cell_1_4))
444+
445+
# In place data migration happens during load, cpuset data is moved to
446+
# pcpuset
447+
self.assertEqual(set(), topo_loaded.cells[0].cpuset)
448+
self.assertEqual({0, 1}, topo_loaded.cells[0].pcpuset)
449+
# but the object version isn't bumped. So when the
450+
# data is saved back to the DB it still has the old version 1.4, but
451+
# also it has the new pcpuset field from version 1.6. This is bug
452+
# https://bugs.launchpad.net/nova/+bug/2097359.
453+
self.assertEqual('1.4', topo_loaded.cells[0].VERSION)
454+
414455

415456
class TestInstanceNUMATopology(
416457
test_objects._LocalTest, _TestInstanceNUMATopology,

0 commit comments

Comments
 (0)