Skip to content

Commit 8b33ac0

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. Related-Bug: #1815989 Closes-Bug: #1901707 Change-Id: Id2d8d72d30075200d2b07b847c4e5568599b0d3b
1 parent 048250a commit 8b33ac0

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

nova/compute/manager.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8055,12 +8055,12 @@ def _neutron_failed_migration_callback(event_name, instance):
80558055
LOG.error(msg, msg_args)
80568056

80578057
@staticmethod
8058-
def _get_neutron_events_for_live_migration(instance):
8058+
def _get_neutron_events_for_live_migration(instance, migration):
80598059
# We don't generate events if CONF.vif_plugging_timeout=0
80608060
# meaning that the operator disabled using them.
80618061
if CONF.vif_plugging_timeout:
8062-
return [('network-vif-plugged', vif['id'])
8063-
for vif in instance.get_network_info()]
8062+
return (instance.get_network_info()
8063+
.get_live_migration_plug_time_events())
80648064
else:
80658065
return []
80668066

@@ -8131,7 +8131,8 @@ class _BreakWaitForInstanceEvent(Exception):
81318131
"""
81328132
pass
81338133

8134-
events = self._get_neutron_events_for_live_migration(instance)
8134+
events = self._get_neutron_events_for_live_migration(
8135+
instance, migration)
81358136
try:
81368137
if ('block_migration' in migrate_data and
81378138
migrate_data.block_migration):

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: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9256,24 +9256,41 @@ def test_get_neutron_events_for_live_migration_empty(self):
92569256
"""Tests the various ways that _get_neutron_events_for_live_migration
92579257
will return an empty list.
92589258
"""
9259+
migration = mock.Mock()
9260+
migration.is_same_host = lambda: False
9261+
self.assertFalse(migration.is_same_host())
9262+
92599263
# 1. no timeout
92609264
self.flags(vif_plugging_timeout=0)
92619265

92629266
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
92639267
nw_info.return_value = network_model.NetworkInfo(
9264-
[network_model.VIF(uuids.port1)])
9268+
[network_model.VIF(uuids.port1, details={
9269+
network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True})])
9270+
self.assertTrue(nw_info.return_value[0].is_hybrid_plug_enabled())
92659271
self.assertEqual(
92669272
[], self.compute._get_neutron_events_for_live_migration(
9267-
self.instance))
9273+
self.instance, migration))
92689274

92699275
# 2. no VIFs
92709276
self.flags(vif_plugging_timeout=300)
92719277

92729278
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
9273-
nw_info.return_value = []
9279+
nw_info.return_value = network_model.NetworkInfo([])
92749280
self.assertEqual(
92759281
[], self.compute._get_neutron_events_for_live_migration(
9276-
self.instance))
9282+
self.instance, migration))
9283+
9284+
# 3. no plug time events
9285+
with mock.patch.object(self.instance, 'get_network_info') as nw_info:
9286+
nw_info.return_value = network_model.NetworkInfo(
9287+
[network_model.VIF(
9288+
uuids.port1, details={
9289+
network_model.VIF_DETAILS_OVS_HYBRID_PLUG: False})])
9290+
self.assertFalse(nw_info.return_value[0].is_hybrid_plug_enabled())
9291+
self.assertEqual(
9292+
[], self.compute._get_neutron_events_for_live_migration(
9293+
self.instance, migration))
92779294

92789295
@mock.patch('nova.compute.rpcapi.ComputeAPI.pre_live_migration')
92799296
@mock.patch('nova.compute.manager.ComputeManager._post_live_migration')
@@ -9288,9 +9305,11 @@ def test_live_migration_wait_vif_plugged(
92889305
wait_for_vif_plugged=True)
92899306
mock_get_bdms.return_value = objects.BlockDeviceMappingList(objects=[])
92909307
mock_pre_live_mig.return_value = migrate_data
9308+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
92919309
self.instance.info_cache = objects.InstanceInfoCache(
92929310
network_info=network_model.NetworkInfo([
9293-
network_model.VIF(uuids.port1), network_model.VIF(uuids.port2)
9311+
network_model.VIF(uuids.port1, details=details),
9312+
network_model.VIF(uuids.port2, details=details)
92949313
]))
92959314
self.compute._waiting_live_migrations[self.instance.uuid] = (
92969315
self.migration, mock.MagicMock()
@@ -9320,11 +9339,12 @@ def test_live_migration_wait_vif_plugged_old_dest_host(
93209339
of not waiting.
93219340
"""
93229341
migrate_data = objects.LibvirtLiveMigrateData()
9342+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
93239343
mock_get_bdms.return_value = objects.BlockDeviceMappingList(objects=[])
93249344
mock_pre_live_mig.return_value = migrate_data
93259345
self.instance.info_cache = objects.InstanceInfoCache(
93269346
network_info=network_model.NetworkInfo([
9327-
network_model.VIF(uuids.port1)]))
9347+
network_model.VIF(uuids.port1, details=details)]))
93289348
self.compute._waiting_live_migrations[self.instance.uuid] = (
93299349
self.migration, mock.MagicMock()
93309350
)
@@ -9468,9 +9488,11 @@ def test_live_migration_aborted_before_running(self, mock_rpc,
94689488
mock_get_bdms.return_value = source_bdms
94699489
migrate_data = objects.LibvirtLiveMigrateData(
94709490
wait_for_vif_plugged=True)
9491+
details = {network_model.VIF_DETAILS_OVS_HYBRID_PLUG: True}
94719492
self.instance.info_cache = objects.InstanceInfoCache(
94729493
network_info=network_model.NetworkInfo([
9473-
network_model.VIF(uuids.port1), network_model.VIF(uuids.port2)
9494+
network_model.VIF(uuids.port1, details=details),
9495+
network_model.VIF(uuids.port2, details=details)
94749496
]))
94759497
self.compute._waiting_live_migrations = {}
94769498
fake_migration = objects.Migration(

0 commit comments

Comments
 (0)