Skip to content

Commit ef348c4

Browse files
committed
only wait for plugtime events in pre-live-migration
This change modifies _get_neutron_events_for_live_migration to filter the event to just the subset that will be sent at plug-time. Currently neuton has a bug where by the dhcp agent send a network-vif-plugged event during live migration after we update the port profile with "migrating-to:" this cause a network-vif-plugged event to be sent for configuration where vif_plugging in nova/os-vif is a noop. when that is corrected the current logic in nova cause the migration to time out as its waiting for an event that will never arrive. This change filters the set of events we wait for to just the plug time events. This backport has squashed the follow up change I37c712ba9a0ab88c44d10f80da3254ab6c463a68 to remove the unused migration paramater orginally added by this patch to _get_neutron_events_for_live_migration Related-Bug: #1815989 Closes-Bug: #1901707 Change-Id: Id2d8d72d30075200d2b07b847c4e5568599b0d3b (cherry picked from commit 8b33ac0)
1 parent d3968f1 commit ef348c4

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

nova/compute/manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8053,8 +8053,8 @@ def _get_neutron_events_for_live_migration(instance):
80538053
# We don't generate events if CONF.vif_plugging_timeout=0
80548054
# meaning that the operator disabled using them.
80558055
if CONF.vif_plugging_timeout:
8056-
return [('network-vif-plugged', vif['id'])
8057-
for vif in instance.get_network_info()]
8056+
return (instance.get_network_info()
8057+
.get_live_migration_plug_time_events())
80588058
else:
80598059
return []
80608060

nova/network/model.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,14 @@ def has_bind_time_event(self, migration):
469469
return (self.is_hybrid_plug_enabled() and not
470470
migration.is_same_host())
471471

472+
@property
473+
def has_live_migration_plug_time_event(self):
474+
"""Returns whether this VIF's network-vif-plugged external event will
475+
be sent by Neutron at "plugtime" - in other words, as soon as neutron
476+
completes configuring the network backend.
477+
"""
478+
return self.is_hybrid_plug_enabled()
479+
472480
def is_hybrid_plug_enabled(self):
473481
return self['details'].get(VIF_DETAILS_OVS_HYBRID_PLUG, False)
474482

@@ -530,15 +538,22 @@ def json(self):
530538
return jsonutils.dumps(self)
531539

532540
def get_bind_time_events(self, migration):
533-
"""Returns whether any of our VIFs have "bind-time" events. See
534-
has_bind_time_event() docstring for more details.
541+
"""Returns a list of external events for any VIFs that have
542+
"bind-time" events during cold migration.
535543
"""
536544
return [('network-vif-plugged', vif['id'])
537545
for vif in self if vif.has_bind_time_event(migration)]
538546

547+
def get_live_migration_plug_time_events(self):
548+
"""Returns a list of external events for any VIFs that have
549+
"plug-time" events during live migration.
550+
"""
551+
return [('network-vif-plugged', vif['id'])
552+
for vif in self if vif.has_live_migration_plug_time_event]
553+
539554
def get_plug_time_events(self, migration):
540-
"""Complementary to get_bind_time_events(), any event that does not
541-
fall in that category is a plug-time event.
555+
"""Returns a list of external events for any VIFs that have
556+
"plug-time" events during cold migration.
542557
"""
543558
return [('network-vif-plugged', vif['id'])
544559
for vif in self if not vif.has_bind_time_event(migration)]

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9320,12 +9320,18 @@ def test_get_neutron_events_for_live_migration_empty(self):
93209320
"""Tests the various ways that _get_neutron_events_for_live_migration
93219321
will return an empty list.
93229322
"""
9323+
migration = mock.Mock()
9324+
migration.is_same_host = lambda: False
9325+
self.assertFalse(migration.is_same_host())
9326+
93239327
# 1. no timeout
93249328
self.flags(vif_plugging_timeout=0)
93259329

93269330
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
93279331
nw_info.return_value = network_model.NetworkInfo(
9328-
[network_model.VIF(uuids.port1)])
9332+
[network_model.VIF(uuids.port1, details={
9333+
network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True})])
9334+
self.assertTrue(nw_info.return_value[0].is_hybrid_plug_enabled())
93299335
self.assertEqual(
93309336
[], self.compute._get_neutron_events_for_live_migration(
93319337
self.instance))
@@ -9334,7 +9340,18 @@ def test_get_neutron_events_for_live_migration_empty(self):
93349340
self.flags(vif_plugging_timeout=300)
93359341

93369342
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
9337-
nw_info.return_value = []
9343+
nw_info.return_value = network_model.NetworkInfo([])
9344+
self.assertEqual(
9345+
[], self.compute._get_neutron_events_for_live_migration(
9346+
self.instance))
9347+
9348+
# 3. no plug time events
9349+
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
9350+
nw_info.return_value = network_model.NetworkInfo(
9351+
[network_model.VIF(
9352+
uuids.port1, details={
9353+
network_model.VIF_DETAILS_OVS_HYBRID_PLUG: False})])
9354+
self.assertFalse(nw_info.return_value[0].is_hybrid_plug_enabled())
93389355
self.assertEqual(
93399356
[], self.compute._get_neutron_events_for_live_migration(
93409357
self.instance))
@@ -9352,9 +9369,11 @@ def test_live_migration_wait_vif_plugged(
93529369
wait_for_vif_plugged=True)
93539370
mock_get_bdms.return_value = objects.BlockDeviceMappingList(objects=[])
93549371
mock_pre_live_mig.return_value = migrate_data
9372+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
93559373
self.instance.info_cache = objects.InstanceInfoCache(
93569374
network_info=network_model.NetworkInfo([
9357-
network_model.VIF(uuids.port1), network_model.VIF(uuids.port2)
9375+
network_model.VIF(uuids.port1, details=details),
9376+
network_model.VIF(uuids.port2, details=details)
93589377
]))
93599378
self.compute._waiting_live_migrations[self.instance.uuid] = (
93609379
self.migration, mock.MagicMock()
@@ -9384,11 +9403,12 @@ def test_live_migration_wait_vif_plugged_old_dest_host(
93849403
of not waiting.
93859404
"""
93869405
migrate_data = objects.LibvirtLiveMigrateData()
9406+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
93879407
mock_get_bdms.return_value = objects.BlockDeviceMappingList(objects=[])
93889408
mock_pre_live_mig.return_value = migrate_data
93899409
self.instance.info_cache = objects.InstanceInfoCache(
93909410
network_info=network_model.NetworkInfo([
9391-
network_model.VIF(uuids.port1)]))
9411+
network_model.VIF(uuids.port1, details=details)]))
93929412
self.compute._waiting_live_migrations[self.instance.uuid] = (
93939413
self.migration, mock.MagicMock()
93949414
)
@@ -9532,9 +9552,11 @@ def test_live_migration_aborted_before_running(self, mock_rpc,
95329552
mock_get_bdms.return_value = source_bdms
95339553
migrate_data = objects.LibvirtLiveMigrateData(
95349554
wait_for_vif_plugged=True)
9555+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
95359556
self.instance.info_cache = objects.InstanceInfoCache(
95369557
network_info=network_model.NetworkInfo([
9537-
network_model.VIF(uuids.port1), network_model.VIF(uuids.port2)
9558+
network_model.VIF(uuids.port1, details=details),
9559+
network_model.VIF(uuids.port2, details=details)
95389560
]))
95399561
self.compute._waiting_live_migrations = {}
95409562
fake_migration = objects.Migration(

0 commit comments

Comments
 (0)