Skip to content

Commit d45bbdd

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Move get_pci_mapping_for_migration to MigrationContext" into stable/stein
2 parents ebf2280 + 84bb00a commit d45bbdd

File tree

4 files changed

+85
-81
lines changed

4 files changed

+85
-81
lines changed

nova/network/neutronv2/api.py

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,45 +3253,14 @@ def cleanup_instance_network_on_host(self, context, instance, host):
32533253
# device_id field on the port which is not what we'd want for shelve.
32543254
pass
32553255

3256-
def _get_pci_devices_from_migration_context(self, migration_context,
3257-
migration):
3258-
if migration and migration.get('status') == 'reverted':
3259-
# In case of revert, swap old and new devices to
3260-
# update the ports back to the original devices.
3261-
return (migration_context.new_pci_devices,
3262-
migration_context.old_pci_devices)
3263-
return (migration_context.old_pci_devices,
3264-
migration_context.new_pci_devices)
3265-
3266-
def _get_pci_mapping_for_migration(self, context, instance, migration):
3267-
"""Get the mapping between the old PCI devices and the new PCI
3268-
devices that have been allocated during this migration. The
3269-
correlation is based on PCI request ID which is unique per PCI
3270-
devices for SR-IOV ports.
3271-
3272-
:param context: The request context.
3273-
:param instance: Get PCI mapping for this instance.
3274-
:param migration: The migration for this instance.
3275-
:Returns: dictionary of mapping {'<old pci address>': <New PciDevice>}
3276-
"""
3277-
migration_context = instance.migration_context
3278-
if not migration_context:
3256+
def _get_pci_mapping_for_migration(self, instance, migration):
3257+
if not instance.migration_context:
32793258
return {}
3280-
3281-
old_pci_devices, new_pci_devices = \
3282-
self._get_pci_devices_from_migration_context(migration_context,
3283-
migration)
3284-
if old_pci_devices and new_pci_devices:
3285-
LOG.debug("Determining PCI devices mapping using migration "
3286-
"context: old_pci_devices: %(old)s, "
3287-
"new_pci_devices: %(new)s",
3288-
{'old': [dev for dev in old_pci_devices],
3289-
'new': [dev for dev in new_pci_devices]})
3290-
return {old.address: new
3291-
for old in old_pci_devices
3292-
for new in new_pci_devices
3293-
if old.request_id == new.request_id}
3294-
return {}
3259+
# In case of revert, swap old and new devices to
3260+
# update the ports back to the original devices.
3261+
revert = (migration and
3262+
migration.get('status') == 'reverted')
3263+
return instance.migration_context.get_pci_mapping_for_migration(revert)
32953264

32963265
def _update_port_binding_for_instance(self, context, instance, host,
32973266
migration=None):
@@ -3337,7 +3306,7 @@ def _update_port_binding_for_instance(self, context, instance, host,
33373306
if (vnic_type in network_model.VNIC_TYPES_SRIOV
33383307
and migration is not None):
33393308
if not pci_mapping:
3340-
pci_mapping = self._get_pci_mapping_for_migration(context,
3309+
pci_mapping = self._get_pci_mapping_for_migration(
33413310
instance, migration)
33423311

33433312
pci_slot = binding_profile.get('pci_slot')

nova/objects/migration_context.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
from oslo_log import log as logging
1516
from oslo_serialization import jsonutils
1617
from oslo_utils import versionutils
1718

@@ -20,6 +21,8 @@
2021
from nova.objects import base
2122
from nova.objects import fields
2223

24+
LOG = logging.getLogger(__name__)
25+
2326

2427
@base.NovaObjectRegistry.register
2528
class MigrationContext(base.NovaPersistentObject, base.NovaObject):
@@ -80,3 +83,32 @@ def get_by_instance_uuid(cls, context, instance_uuid):
8083
return None
8184

8285
return cls.obj_from_db_obj(db_extra['migration_context'])
86+
87+
def get_pci_mapping_for_migration(self, revert):
88+
"""Get the mapping between the old PCI devices and the new PCI
89+
devices that have been allocated during this migration. The
90+
correlation is based on PCI request ID which is unique per PCI
91+
devices for SR-IOV ports.
92+
93+
:param revert: If True, return a reverse mapping i.e
94+
mapping between new PCI devices and old PCI devices.
95+
:returns: dictionary of PCI mapping.
96+
if revert==False:
97+
{'<old pci address>': <New PciDevice>}
98+
if revert==True:
99+
{'<new pci address>': <Old PciDevice>}
100+
"""
101+
step = -1 if revert else 1
102+
current_pci_devs, updated_pci_devs = (self.old_pci_devices,
103+
self.new_pci_devices)[::step]
104+
if current_pci_devs and updated_pci_devs:
105+
LOG.debug("Determining PCI devices mapping using migration "
106+
"context: current_pci_devs: %(cur)s, "
107+
"updated_pci_devs: %(upd)s",
108+
{'cur': [dev for dev in current_pci_devs],
109+
'upd': [dev for dev in updated_pci_devs]})
110+
return {curr_dev.address: upd_dev
111+
for curr_dev in current_pci_devs
112+
for upd_dev in updated_pci_devs
113+
if curr_dev.request_id == upd_dev.request_id}
114+
return {}

nova/tests/unit/network/test_neutronv2.py

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4681,56 +4681,29 @@ def test_update_port_bindings_for_instance_with_diff_host_unbound_vif_type(
46814681
def test_get_pci_mapping_for_migration(self):
46824682
instance = fake_instance.fake_instance_obj(self.context)
46834683
instance.migration_context = objects.MigrationContext()
4684-
old_pci_devices = objects.PciDeviceList(
4685-
objects=[objects.PciDevice(vendor_id='1377',
4686-
product_id='0047',
4687-
address='0000:0a:00.1',
4688-
compute_node_id=1,
4689-
request_id='1234567890')])
4690-
4691-
new_pci_devices = objects.PciDeviceList(
4692-
objects=[objects.PciDevice(vendor_id='1377',
4693-
product_id='0047',
4694-
address='0000:0b:00.1',
4695-
compute_node_id=2,
4696-
request_id='1234567890')])
4697-
4698-
instance.migration_context.old_pci_devices = old_pci_devices
4699-
instance.migration_context.new_pci_devices = new_pci_devices
4700-
instance.pci_devices = instance.migration_context.old_pci_devices
47014684
migration = {'status': 'confirmed'}
47024685

4703-
pci_mapping = self.api._get_pci_mapping_for_migration(
4704-
self.context, instance, migration)
4705-
self.assertEqual(
4706-
{old_pci_devices[0].address: new_pci_devices[0]}, pci_mapping)
4686+
with mock.patch.object(instance.migration_context,
4687+
'get_pci_mapping_for_migration') as map_func:
4688+
self.api._get_pci_mapping_for_migration(instance, migration)
4689+
map_func.assert_called_with(False)
47074690

47084691
def test_get_pci_mapping_for_migration_reverted(self):
47094692
instance = fake_instance.fake_instance_obj(self.context)
47104693
instance.migration_context = objects.MigrationContext()
4711-
old_pci_devices = objects.PciDeviceList(
4712-
objects=[objects.PciDevice(vendor_id='1377',
4713-
product_id='0047',
4714-
address='0000:0a:00.1',
4715-
compute_node_id=1,
4716-
request_id='1234567890')])
4717-
4718-
new_pci_devices = objects.PciDeviceList(
4719-
objects=[objects.PciDevice(vendor_id='1377',
4720-
product_id='0047',
4721-
address='0000:0b:00.1',
4722-
compute_node_id=2,
4723-
request_id='1234567890')])
4724-
4725-
instance.migration_context.old_pci_devices = old_pci_devices
4726-
instance.migration_context.new_pci_devices = new_pci_devices
4727-
instance.pci_devices = instance.migration_context.old_pci_devices
47284694
migration = {'status': 'reverted'}
47294695

4696+
with mock.patch.object(instance.migration_context,
4697+
'get_pci_mapping_for_migration') as map_func:
4698+
self.api._get_pci_mapping_for_migration(instance, migration)
4699+
map_func.assert_called_with(True)
4700+
4701+
def test_get_pci_mapping_for_migration_no_migration_context(self):
4702+
instance = fake_instance.fake_instance_obj(self.context)
4703+
instance.migration_context = None
47304704
pci_mapping = self.api._get_pci_mapping_for_migration(
4731-
self.context, instance, migration)
4732-
self.assertEqual(
4733-
{new_pci_devices[0].address: old_pci_devices[0]}, pci_mapping)
4705+
instance, None)
4706+
self.assertDictEqual({}, pci_mapping)
47344707

47354708
@mock.patch.object(neutronapi, 'get_client', return_value=mock.Mock())
47364709
def test_update_port_profile_for_migration_teardown_false(

nova/tests/unit/objects/test_migration_context.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ def get_fake_migration_context_obj(ctxt):
5252
return obj
5353

5454

55+
def get_fake_migration_context_with_pci_devs(ctxt=None):
56+
obj = get_fake_migration_context_obj(ctxt)
57+
obj.old_pci_devices = objects.PciDeviceList(
58+
objects=[objects.PciDevice(vendor_id='1377',
59+
product_id='0047',
60+
address='0000:0a:00.1',
61+
compute_node_id=1,
62+
request_id=uuids.pcidev)])
63+
obj.new_pci_devices = objects.PciDeviceList(
64+
objects=[objects.PciDevice(vendor_id='1377',
65+
product_id='0047',
66+
address='0000:0b:00.1',
67+
compute_node_id=2,
68+
request_id=uuids.pcidev)])
69+
return obj
70+
71+
5572
class _TestMigrationContext(object):
5673

5774
def _test_get_by_instance_uuid(self, db_data):
@@ -104,7 +121,20 @@ def test_get_by_instance_uuid_missing(self, mock_get):
104121

105122

106123
class TestMigrationContext(test_objects._LocalTest, _TestMigrationContext):
107-
pass
124+
125+
def test_pci_mapping_for_migration(self):
126+
mig_ctx = get_fake_migration_context_with_pci_devs()
127+
pci_mapping = mig_ctx.get_pci_mapping_for_migration(False)
128+
self.assertDictEqual(
129+
{mig_ctx.old_pci_devices[0].address: mig_ctx.new_pci_devices[0]},
130+
pci_mapping)
131+
132+
def test_pci_mapping_for_migration_revert(self):
133+
mig_ctx = get_fake_migration_context_with_pci_devs()
134+
pci_mapping = mig_ctx.get_pci_mapping_for_migration(True)
135+
self.assertDictEqual(
136+
{mig_ctx.new_pci_devices[0].address: mig_ctx.old_pci_devices[0]},
137+
pci_mapping)
108138

109139

110140
class TestMigrationContextRemote(test_objects._RemoteTest,

0 commit comments

Comments
 (0)