Skip to content

Commit 043b0da

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[FUP] Follow-up patch for SR-IOV live migration"
2 parents 3c5aec1 + 7824909 commit 043b0da

File tree

8 files changed

+82
-46
lines changed

8 files changed

+82
-46
lines changed

nova/compute/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6298,7 +6298,7 @@ def check_can_live_migrate_destination(self, ctxt, instance,
62986298
dest_check_data)
62996299
# Create migrate_data vifs
63006300
migrate_data.vifs = \
6301-
migrate_data_obj.LiveMigrateData.create_skeleton_migrate_vifs(
6301+
migrate_data_obj.VIFMigrateData.create_skeleton_migrate_vifs(
63026302
instance.get_network_info())
63036303
# Claim PCI devices for VIFs on destination (if needed)
63046304
port_id_to_pci = self._claim_pci_for_instance_vifs(ctxt, instance)

nova/compute/resource_tracker.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,11 @@ def _move_claim(self, context, instance, new_instance_type, nodename,
309309
new_pci_requests = pci_request.get_pci_requests_from_flavor(
310310
new_instance_type)
311311
new_pci_requests.instance_uuid = instance.uuid
312-
# PCI requests come from two sources: instance flavor and
313-
# SR-IOV ports. SR-IOV ports pci_request don't have an alias_name.
314-
# On resize merge the SR-IOV ports pci_requests with the new
315-
# instance flavor pci_requests.
312+
# On resize merge the SR-IOV ports pci_requests
313+
# with the new instance flavor pci_requests.
316314
if instance.pci_requests:
317315
for request in instance.pci_requests.requests:
318-
if request.alias_name is None:
316+
if request.source == objects.InstancePCIRequest.NEUTRON_PORT:
319317
new_pci_requests.requests.append(request)
320318
claim = claims.MoveClaim(context, instance, nodename,
321319
new_instance_type, image_meta, self, cn,

nova/conductor/tasks/live_migrate.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,8 @@ def _check_can_migrate_pci(self, src_host, dest_host):
214214
return
215215

216216
for pci_request in self.instance.pci_requests.requests:
217-
if pci_request.alias_name is not None:
217+
if pci_request.source != objects.InstancePCIRequest.NEUTRON_PORT:
218218
# allow only VIF related PCI requests in live migration.
219-
# PCI requests come from two sources: instance flavor and
220-
# SR-IOV ports.
221-
# SR-IOV ports pci_request don't have an alias_name.
222-
# TODO(adrianc): add an is_sriov_port property to PCIRequest
223-
# to make this cryptic check clearer (also in resource_tracker)
224-
225219
raise exception.MigrationPreCheckError(
226220
reason= "non-VIF related PCI requests for instance "
227221
"are not allowed for live migration.")
@@ -232,6 +226,7 @@ def _check_can_migrate_pci(self, src_host, dest_host):
232226
raise exception.MigrationPreCheckError(
233227
reason="Cannot live migrate VIF with related PCI, Neutron "
234228
"does not support required port binding extension.")
229+
235230
if not (supports_vif_related_pci_allocations(self.context,
236231
src_host) and
237232
supports_vif_related_pci_allocations(self.context,
@@ -340,8 +335,8 @@ def _call_livem_checks_on_host(self, destination):
340335
# migrate data vifs were not constructed in dest compute
341336
# during check_can_live_migrate_destination, construct a
342337
# skeleton to be updated after port binding.
343-
# TODO(adrianc): This can be removed once we move to T release
344-
self.migrate_data.vifs = migrate_data_obj.LiveMigrateData.\
338+
# TODO(adrianc): This can be removed once we move to U release
339+
self.migrate_data.vifs = migrate_data_obj.VIFMigrateData.\
345340
create_skeleton_migrate_vifs(
346341
self.instance.get_network_info())
347342
bindings = self._bind_ports_on_destination(destination)
@@ -356,7 +351,7 @@ def _bind_ports_on_destination(self, destination):
356351
# that was bound. This information is then stuffed into the
357352
# migrate_data.
358353
try:
359-
# Note(adrianc): migrate_data.vifs was partially filled
354+
# NOTE(adrianc): migrate_data.vifs was partially filled
360355
# by destination compute if compute is new enough.
361356
# if that is the case, it may have updated the required port
362357
# profile for the destination node (e.g new PCI address if SR-IOV)
@@ -372,7 +367,8 @@ def _bind_ports_on_destination(self, destination):
372367
for mig_vif in migrate_vifs_with_profile}
373368

374369
bindings = self.network_api.bind_ports_to_host(
375-
self.context, self.instance, destination, None, ports_profile)
370+
context=self.context, instance=self.instance, host=destination,
371+
vnic_types=None, port_profiles=ports_profile)
376372
except exception.PortBindingFailed as e:
377373
# Port binding failed for that host, try another one.
378374
raise exception.MigrationPreCheckError(

nova/objects/instance_pci_requests.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ class InstancePCIRequest(base.NovaObject,
2828
# Version 1.3: Add requester_id
2929
VERSION = '1.3'
3030

31+
# Possible sources for a PCI request:
32+
# FLAVOR_ALIAS : Request originated from a flavor alias.
33+
# NEUTRON_PORT : Request originated from a neutron port.
34+
FLAVOR_ALIAS = 0
35+
NEUTRON_PORT = 1
36+
3137
fields = {
3238
'count': fields.IntegerField(),
3339
'spec': fields.ListOfDictOfNullableStringsField(),
@@ -40,6 +46,14 @@ class InstancePCIRequest(base.NovaObject,
4046
'numa_policy': fields.PCINUMAAffinityPolicyField(nullable=True),
4147
}
4248

49+
@property
50+
def source(self):
51+
# PCI requests originate from two sources: instance flavor alias and
52+
# neutron SR-IOV ports.
53+
# SR-IOV ports pci_request don't have an alias_name.
54+
return (InstancePCIRequest.NEUTRON_PORT if self.alias_name is None
55+
else InstancePCIRequest.FLAVOR_ALIAS)
56+
4357
def obj_load_attr(self, attr):
4458
setattr(self, attr, None)
4559

nova/objects/migrate_data.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ def get_dest_vif(self):
9494
vif['details'] = self.vif_details
9595
return vif
9696

97+
@classmethod
98+
def create_skeleton_migrate_vifs(cls, vifs):
99+
"""Create migrate vifs for live migration.
100+
101+
:param vifs: a list of VIFs.
102+
:return: list of VIFMigrateData object corresponding to the provided
103+
VIFs.
104+
"""
105+
vif_mig_data = []
106+
107+
for vif in vifs:
108+
mig_vif = cls(port_id=vif['id'], source_vif=vif)
109+
vif_mig_data.append(mig_vif)
110+
return vif_mig_data
111+
97112

98113
@obj_base.NovaObjectRegistry.register_if(False)
99114
class LiveMigrateData(obj_base.NovaObject):
@@ -120,23 +135,6 @@ class LiveMigrateData(obj_base.NovaObject):
120135
'vifs': fields.ListOfObjectsField('VIFMigrateData'),
121136
}
122137

123-
@staticmethod
124-
def create_skeleton_migrate_vifs(vifs):
125-
"""Create migrate vifs for live migration.
126-
127-
:param vifs: a list of VIFs.
128-
:return: list of VIFMigrateData object corresponding to the provided
129-
VIFs.
130-
"""
131-
vif_mig_data = []
132-
133-
for vif in vifs:
134-
mig_vif = VIFMigrateData(
135-
port_id=vif['id'],
136-
source_vif=vif)
137-
vif_mig_data.append(mig_vif)
138-
return vif_mig_data
139-
140138

141139
@obj_base.NovaObjectRegistry.register
142140
class LibvirtLiveMigrateBDMInfo(obj_base.NovaObject):

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2716,7 +2716,7 @@ def _test_check_can_live_migrate_destination(self, do_raise=False):
27162716
'cleanup_live_migration_destination_check'),
27172717
mock.patch.object(db, 'instance_fault_create'),
27182718
mock.patch.object(compute_utils, 'EventReporter'),
2719-
mock.patch.object(migrate_data_obj.LiveMigrateData,
2719+
mock.patch.object(migrate_data_obj.VIFMigrateData,
27202720
'create_skeleton_migrate_vifs'),
27212721
mock.patch.object(instance, 'get_network_info'),
27222722
mock.patch.object(self.compute, '_claim_pci_for_instance_vifs'),
@@ -8911,7 +8911,7 @@ def fake_reschedule_resize_or_reraise(*args, **kwargs):
89118911
# (_error_out_instance_on_exception will set to ACTIVE by default).
89128912
self.assertEqual(vm_states.STOPPED, instance.vm_state)
89138913

8914-
def test__claim_pci_for_instance_vifs(self):
8914+
def test__claim_pci_for_instance_no_vifs(self):
89158915
@mock.patch.object(self.compute, 'rt')
89168916
@mock.patch.object(pci_request, 'get_instance_pci_request_from_vif')
89178917
@mock.patch.object(self.instance, 'get_network_info')
@@ -8925,6 +8925,16 @@ def _test(mock_get_network_info,
89258925
self.instance)
89268926
rt_mock.claim_pci_devices.assert_not_called()
89278927
self.assertEqual(0, len(port_id_to_pci))
8928+
8929+
_test()
8930+
8931+
def test__claim_pci_for_instance_vifs(self):
8932+
@mock.patch.object(self.compute, 'rt')
8933+
@mock.patch.object(pci_request, 'get_instance_pci_request_from_vif')
8934+
@mock.patch.object(self.instance, 'get_network_info')
8935+
def _test(mock_get_network_info,
8936+
mock_get_instance_pci_request_from_vif,
8937+
rt_mock):
89288938
# when there are VIFs, expect only ones with related PCI to be
89298939
# claimed and their migrate vif profile to be updated.
89308940

@@ -9001,7 +9011,7 @@ def test__update_migrate_vifs_profile_with_pci(self):
90019011
vendor_id='15b3',
90029012
product_id='1018')
90039013
port_id_to_pci_dev = {uuids.port0: pci_dev}
9004-
mig_vifs = migrate_data_obj.LiveMigrateData.\
9014+
mig_vifs = migrate_data_obj.VIFMigrateData.\
90059015
create_skeleton_migrate_vifs(nw_vifs)
90069016
self.compute._update_migrate_vifs_profile_with_pci(mig_vifs,
90079017
port_id_to_pci_dev)

nova/tests/unit/objects/test_instance_pci_requests.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ def test_obj_make_compatible_pre_1_3(self):
181181
self.assertNotIn('requester_id', primitive['nova_object.data'])
182182
self.assertIn('numa_policy', primitive['nova_object.data'])
183183

184+
def test_source_property(self):
185+
neutron_port_pci_req = objects.InstancePCIRequest(
186+
count=1,
187+
spec=[{'vendor_id': '15b3', 'device_id': '1018'}],
188+
request_id=uuids.pci_request_id1,
189+
requester_id=uuids.requester_id1,
190+
alias_name = None)
191+
flavor_alias_pci_req = objects.InstancePCIRequest(
192+
count=1,
193+
spec=[{'vendor_id': '15b3', 'device_id': '1810'}],
194+
request_id=uuids.pci_request_id2,
195+
requester_id=uuids.requester_id2,
196+
alias_name = 'alias_1')
197+
self.assertEqual(neutron_port_pci_req.source,
198+
objects.InstancePCIRequest.NEUTRON_PORT)
199+
self.assertEqual(flavor_alias_pci_req.source,
200+
objects.InstancePCIRequest.FLAVOR_ALIAS)
201+
184202

185203
class TestInstancePCIRequests(test_objects._LocalTest,
186204
_TestInstancePCIRequests):

nova/tests/unit/objects/test_migrate_data.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,7 @@ def test_obj_make_compatible(self):
4444

4545
class TestLiveMigrateData(test_objects._LocalTest,
4646
_TestLiveMigrateData):
47-
def test_create_skeleton_migrate_vifs(self):
48-
vifs = [
49-
network_model.VIF(id=uuids.port1),
50-
network_model.VIF(id=uuids.port2)]
51-
mig_vifs = migrate_data.LiveMigrateData.create_skeleton_migrate_vifs(
52-
vifs)
53-
self.assertEqual(len(vifs), len(mig_vifs))
54-
self.assertEqual([vif['id'] for vif in vifs],
55-
[mig_vif.port_id for mig_vif in mig_vifs])
47+
pass
5648

5749

5850
class TestRemoteLiveMigrateData(test_objects._RemoteTest,
@@ -311,3 +303,13 @@ def test_get_dest_vif(self):
311303
self.assertEqual(migrate_vif.vif_details, dest_vif['details'])
312304
self.assertEqual(migrate_vif.profile, dest_vif['profile'])
313305
self.assertEqual(uuids.ovs_interfaceid, dest_vif['ovs_interfaceid'])
306+
307+
def test_create_skeleton_migrate_vifs(self):
308+
vifs = [
309+
network_model.VIF(id=uuids.port1),
310+
network_model.VIF(id=uuids.port2)]
311+
mig_vifs = migrate_data.VIFMigrateData.create_skeleton_migrate_vifs(
312+
vifs)
313+
self.assertEqual(len(vifs), len(mig_vifs))
314+
self.assertEqual([vif['id'] for vif in vifs],
315+
[mig_vif.port_id for mig_vif in mig_vifs])

0 commit comments

Comments
 (0)