summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Smith <dansmith@redhat.com>2018-08-14 08:31:41 -0700
committerDan Smith <dansmith@redhat.com>2018-08-14 08:31:41 -0700
commitb1b5a5eb96ec8f222e5bad9055ec7baeed9767cd (patch)
treeae229a2ab1f9eb3a7bf2c5b65c9290f4191bfa97
parentf58645115255e784a08a0281c6c731186737a993 (diff)
Revert "libvirt: slow live-migration to ensure network is ready"stable/pike
Notes
Notes (review): Code-Review+2: Matt Riedemann <mriedem.os@gmail.com> Code-Review+2: Lee Yarwood <lyarwood@redhat.com> Workflow+1: Lee Yarwood <lyarwood@redhat.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Wed, 15 Aug 2018 23:16:49 +0000 Reviewed-on: https://review.openstack.org/591762 Project: openstack/nova Branch: refs/heads/stable/pike
-rwxr-xr-xnova/tests/unit/virt/libvirt/test_driver.py213
-rw-r--r--nova/tests/unit/virt/test_virt_drivers.py2
-rw-r--r--nova/virt/libvirt/driver.py80
-rw-r--r--releasenotes/notes/bug-1414559-880d6b3c1ce3b95e.yaml8
4 files changed, 31 insertions, 272 deletions
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index baead43..cb70915 100755
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -8511,7 +8511,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8511 vdmock = self.mox.CreateMock(fakelibvirt.virDomain) 8511 vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
8512 guest = libvirt_guest.Guest(vdmock) 8512 guest = libvirt_guest.Guest(vdmock)
8513 self.mox.StubOutWithMock(vdmock, "migrateToURI2") 8513 self.mox.StubOutWithMock(vdmock, "migrateToURI2")
8514 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW 8514 _bandwidth = CONF.libvirt.live_migration_bandwidth
8515 vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn( 8515 vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn(
8516 initial_xml) 8516 initial_xml)
8517 vdmock.migrateToURI2(drvr._live_migration_uri('dest'), 8517 vdmock.migrateToURI2(drvr._live_migration_uri('dest'),
@@ -8533,8 +8533,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8533 self.assertRaises(fakelibvirt.libvirtError, 8533 self.assertRaises(fakelibvirt.libvirtError,
8534 drvr._live_migration_operation, 8534 drvr._live_migration_operation,
8535 self.context, instance_ref, 'dest', 8535 self.context, instance_ref, 'dest',
8536 False, migrate_data, guest, [], 8536 False, migrate_data, guest, [])
8537 _bandwidth)
8538 8537
8539 def test_live_migration_parallels_no_new_xml(self): 8538 def test_live_migration_parallels_no_new_xml(self):
8540 self.flags(virt_type='parallels', group='libvirt') 8539 self.flags(virt_type='parallels', group='libvirt')
@@ -8549,14 +8548,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8549 block_migration=False) 8548 block_migration=False)
8550 dom_mock = mock.MagicMock() 8549 dom_mock = mock.MagicMock()
8551 guest = libvirt_guest.Guest(dom_mock) 8550 guest = libvirt_guest.Guest(dom_mock)
8552 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
8553 drvr._live_migration_operation(self.context, instance, 'dest', 8551 drvr._live_migration_operation(self.context, instance, 'dest',
8554 False, migrate_data, guest, [], 8552 False, migrate_data, guest, [])
8555 bandwidth=_bandwidth)
8556 # when new xml is not passed we fall back to migrateToURI 8553 # when new xml is not passed we fall back to migrateToURI
8557 dom_mock.migrateToURI.assert_called_once_with( 8554 dom_mock.migrateToURI.assert_called_once_with(
8558 drvr._live_migration_uri('dest'), 8555 drvr._live_migration_uri('dest'),
8559 flags=0, bandwidth=_bandwidth) 8556 flags=0, bandwidth=0)
8560 8557
8561 @mock.patch.object(utils, 'spawn') 8558 @mock.patch.object(utils, 'spawn')
8562 @mock.patch.object(host.Host, 'get_guest') 8559 @mock.patch.object(host.Host, 'get_guest')
@@ -8578,13 +8575,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8578 'power_state': power_state.RUNNING, 8575 'power_state': power_state.RUNNING,
8579 'vm_state': vm_states.ACTIVE}) 8576 'vm_state': vm_states.ACTIVE})
8580 instance = objects.Instance(**instance_dict) 8577 instance = objects.Instance(**instance_dict)
8581 instance.info_cache = objects.InstanceInfoCache(
8582 network_info=_fake_network_info(self, 1))
8583 migrate_data = objects.LibvirtLiveMigrateData( 8578 migrate_data = objects.LibvirtLiveMigrateData(
8584 block_migration=True) 8579 block_migration=True)
8585 dom = fakelibvirt.Domain(drvr._get_connection(), '<domain/>', True) 8580 dom = fakelibvirt.Domain(drvr._get_connection(), '<domain/>', True)
8586 guest = libvirt_guest.Guest(dom) 8581 guest = libvirt_guest.Guest(dom)
8587 guest.migrate_configure_max_speed = mock.MagicMock()
8588 mock_guest.return_value = guest 8582 mock_guest.return_value = guest
8589 drvr._live_migration(self.context, instance, 'dest', 8583 drvr._live_migration(self.context, instance, 'dest',
8590 lambda: None, lambda: None, True, 8584 lambda: None, lambda: None, True,
@@ -8593,9 +8587,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8593 mock_thread.assert_called_once_with( 8587 mock_thread.assert_called_once_with(
8594 drvr._live_migration_operation, 8588 drvr._live_migration_operation,
8595 self.context, instance, 'dest', True, 8589 self.context, instance, 'dest', True,
8596 migrate_data, guest, [], libvirt_driver.MIN_MIGRATION_SPEED_BW) 8590 migrate_data, guest, [])
8597 guest.migrate_configure_max_speed.assert_called_once_with(
8598 CONF.libvirt.live_migration_bandwidth)
8599 8591
8600 def test_live_migration_update_volume_xml(self): 8592 def test_live_migration_update_volume_xml(self):
8601 self.compute = manager.ComputeManager() 8593 self.compute = manager.ComputeManager()
@@ -8647,8 +8639,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8647 test_mock.XMLDesc.return_value = target_xml 8639 test_mock.XMLDesc.return_value = target_xml
8648 self.assertFalse(drvr._live_migration_operation( 8640 self.assertFalse(drvr._live_migration_operation(
8649 self.context, instance_ref, 'dest', False, 8641 self.context, instance_ref, 'dest', False,
8650 migrate_data, guest, [], 8642 migrate_data, guest, []))
8651 libvirt_driver.MIN_MIGRATION_SPEED_BW))
8652 mupdate.assert_called_once_with( 8643 mupdate.assert_called_once_with(
8653 guest, migrate_data, mock.ANY) 8644 guest, migrate_data, mock.ANY)
8654 8645
@@ -8688,7 +8679,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8688 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) 8679 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
8689 test_mock = mock.MagicMock() 8680 test_mock = mock.MagicMock()
8690 guest = libvirt_guest.Guest(test_mock) 8681 guest = libvirt_guest.Guest(test_mock)
8691 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
8692 8682
8693 with mock.patch.object(libvirt_migrate, 8683 with mock.patch.object(libvirt_migrate,
8694 'get_updated_guest_xml') as mupdate: 8684 'get_updated_guest_xml') as mupdate:
@@ -8696,11 +8686,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8696 test_mock.XMLDesc.return_value = target_xml 8686 test_mock.XMLDesc.return_value = target_xml
8697 drvr._live_migration_operation(self.context, instance_ref, 8687 drvr._live_migration_operation(self.context, instance_ref,
8698 'dest', False, migrate_data, 8688 'dest', False, migrate_data,
8699 guest, [], _bandwidth) 8689 guest, [])
8700 test_mock.migrateToURI2.assert_called_once_with( 8690 test_mock.migrateToURI2.assert_called_once_with(
8701 'qemu+tcp://127.0.0.2/system', 8691 'qemu+tcp://127.0.0.2/system',
8702 miguri='tcp://127.0.0.2', 8692 miguri='tcp://127.0.0.2',
8703 dxml=mupdate(), flags=0, bandwidth=_bandwidth) 8693 dxml=mupdate(), flags=0, bandwidth=0)
8704 8694
8705 def test_update_volume_xml(self): 8695 def test_update_volume_xml(self):
8706 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) 8696 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@@ -8961,7 +8951,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8961 mock_migrate.side_effect = fakelibvirt.libvirtError("ERR") 8951 mock_migrate.side_effect = fakelibvirt.libvirtError("ERR")
8962 8952
8963 # start test 8953 # start test
8964 bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW 8954 bandwidth = CONF.libvirt.live_migration_bandwidth
8965 migrate_data = objects.LibvirtLiveMigrateData( 8955 migrate_data = objects.LibvirtLiveMigrateData(
8966 graphics_listen_addr_vnc='10.0.0.1', 8956 graphics_listen_addr_vnc='10.0.0.1',
8967 graphics_listen_addr_spice='10.0.0.2', 8957 graphics_listen_addr_spice='10.0.0.2',
@@ -8976,8 +8966,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
8976 self.assertRaises(fakelibvirt.libvirtError, 8966 self.assertRaises(fakelibvirt.libvirtError,
8977 drvr._live_migration_operation, 8967 drvr._live_migration_operation,
8978 self.context, instance_ref, 'dest', 8968 self.context, instance_ref, 'dest',
8979 False, migrate_data, guest, [], 8969 False, migrate_data, guest, [])
8980 bandwidth=bandwidth)
8981 mock_xml.assert_called_once_with( 8970 mock_xml.assert_called_once_with(
8982 flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE) 8971 flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE)
8983 mock_migrate.assert_called_once_with( 8972 mock_migrate.assert_called_once_with(
@@ -9009,8 +8998,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9009 self.assertRaises(exception.MigrationError, 8998 self.assertRaises(exception.MigrationError,
9010 drvr._live_migration_operation, 8999 drvr._live_migration_operation,
9011 self.context, instance_ref, 'dest', 9000 self.context, instance_ref, 'dest',
9012 False, migrate_data, guest, [], 9001 False, migrate_data, guest, [])
9013 bandwidth=libvirt_driver.MIN_MIGRATION_SPEED_BW)
9014 9002
9015 @mock.patch.object(host.Host, 'has_min_version', return_value=True) 9003 @mock.patch.object(host.Host, 'has_min_version', return_value=True)
9016 @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3") 9004 @mock.patch.object(fakelibvirt.virDomain, "migrateToURI3")
@@ -9025,7 +9013,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9025 disk_paths = ['vda', 'vdb'] 9013 disk_paths = ['vda', 'vdb']
9026 params = { 9014 params = {
9027 'migrate_disks': ['vda', 'vdb'], 9015 'migrate_disks': ['vda', 'vdb'],
9028 'bandwidth': libvirt_driver.MIN_MIGRATION_SPEED_BW, 9016 'bandwidth': CONF.libvirt.live_migration_bandwidth,
9029 'destination_xml': '', 9017 'destination_xml': '',
9030 } 9018 }
9031 mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR") 9019 mock_migrateToURI3.side_effect = fakelibvirt.libvirtError("ERR")
@@ -9047,8 +9035,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9047 self.assertRaises(fakelibvirt.libvirtError, 9035 self.assertRaises(fakelibvirt.libvirtError,
9048 drvr._live_migration_operation, 9036 drvr._live_migration_operation,
9049 self.context, instance, 'dest', 9037 self.context, instance, 'dest',
9050 False, migrate_data, guest, disk_paths, 9038 False, migrate_data, guest, disk_paths)
9051 libvirt_driver.MIN_MIGRATION_SPEED_BW)
9052 mock_migrateToURI3.assert_called_once_with( 9039 mock_migrateToURI3.assert_called_once_with(
9053 drvr._live_migration_uri('dest'), 9040 drvr._live_migration_uri('dest'),
9054 params=params, flags=0) 9041 params=params, flags=0)
@@ -9073,15 +9060,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9073 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) 9060 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9074 drvr._parse_migration_flags() 9061 drvr._parse_migration_flags()
9075 9062
9076 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
9077 instance = objects.Instance(**self.test_instance) 9063 instance = objects.Instance(**self.test_instance)
9078 drvr._live_migration_operation(self.context, instance, 'dest', 9064 drvr._live_migration_operation(self.context, instance, 'dest',
9079 True, migrate_data, guest, 9065 True, migrate_data, guest,
9080 device_names, _bandwidth) 9066 device_names)
9081 9067
9082 params = { 9068 params = {
9083 'migrate_disks': device_names, 9069 'migrate_disks': device_names,
9084 'bandwidth': _bandwidth, 9070 'bandwidth': CONF.libvirt.live_migration_bandwidth,
9085 'destination_xml': b'<xml/>', 9071 'destination_xml': b'<xml/>',
9086 } 9072 }
9087 mock_migrateToURI3.assert_called_once_with( 9073 mock_migrateToURI3.assert_called_once_with(
@@ -9120,9 +9106,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9120 self.flags(live_migration_tunnelled=True, group='libvirt') 9106 self.flags(live_migration_tunnelled=True, group='libvirt')
9121 # Preparing mocks 9107 # Preparing mocks
9122 disk_paths = [] 9108 disk_paths = []
9123 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW
9124 params = { 9109 params = {
9125 'bandwidth': _bandwidth, 9110 'bandwidth': CONF.libvirt.live_migration_bandwidth,
9126 'destination_xml': '', 9111 'destination_xml': '',
9127 } 9112 }
9128 # Start test 9113 # Start test
@@ -9141,8 +9126,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9141 drvr._parse_migration_flags() 9126 drvr._parse_migration_flags()
9142 instance = objects.Instance(**self.test_instance) 9127 instance = objects.Instance(**self.test_instance)
9143 drvr._live_migration_operation(self.context, instance, 'dest', 9128 drvr._live_migration_operation(self.context, instance, 'dest',
9144 True, migrate_data, guest, disk_paths, 9129 True, migrate_data, guest, disk_paths)
9145 _bandwidth)
9146 expected_flags = (fakelibvirt.VIR_MIGRATE_UNDEFINE_SOURCE | 9130 expected_flags = (fakelibvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
9147 fakelibvirt.VIR_MIGRATE_PERSIST_DEST | 9131 fakelibvirt.VIR_MIGRATE_PERSIST_DEST |
9148 fakelibvirt.VIR_MIGRATE_TUNNELLED | 9132 fakelibvirt.VIR_MIGRATE_TUNNELLED |
@@ -9168,7 +9152,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9168 vdmock = self.mox.CreateMock(fakelibvirt.virDomain) 9152 vdmock = self.mox.CreateMock(fakelibvirt.virDomain)
9169 guest = libvirt_guest.Guest(vdmock) 9153 guest = libvirt_guest.Guest(vdmock)
9170 self.mox.StubOutWithMock(vdmock, "migrateToURI2") 9154 self.mox.StubOutWithMock(vdmock, "migrateToURI2")
9171 _bandwidth = libvirt_driver.MIN_MIGRATION_SPEED_BW 9155 _bandwidth = CONF.libvirt.live_migration_bandwidth
9172 vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE 9156 vdmock.XMLDesc(flags=fakelibvirt.VIR_DOMAIN_XML_MIGRATABLE
9173 ).AndReturn(FakeVirtDomain().XMLDesc(flags=0)) 9157 ).AndReturn(FakeVirtDomain().XMLDesc(flags=0))
9174 vdmock.migrateToURI2(drvr._live_migration_uri('dest'), 9158 vdmock.migrateToURI2(drvr._live_migration_uri('dest'),
@@ -9190,8 +9174,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9190 self.assertRaises(fakelibvirt.libvirtError, 9174 self.assertRaises(fakelibvirt.libvirtError,
9191 drvr._live_migration_operation, 9175 drvr._live_migration_operation,
9192 self.context, instance_ref, 'dest', 9176 self.context, instance_ref, 'dest',
9193 False, migrate_data, guest, [], 9177 False, migrate_data, guest, [])
9194 _bandwidth)
9195 9178
9196 self.assertEqual(vm_states.ACTIVE, instance_ref.vm_state) 9179 self.assertEqual(vm_states.ACTIVE, instance_ref.vm_state)
9197 self.assertEqual(power_state.RUNNING, instance_ref.power_state) 9180 self.assertEqual(power_state.RUNNING, instance_ref.power_state)
@@ -10226,87 +10209,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
10226 def test_live_migration_main(self, mock_copy_disk_path, mock_running, 10209 def test_live_migration_main(self, mock_copy_disk_path, mock_running,
10227 mock_guest, mock_monitor, mock_thread, 10210 mock_guest, mock_monitor, mock_thread,
10228 mock_conn): 10211 mock_conn):
10229 virtapi = manager.ComputeVirtAPI(mock.MagicMock())
10230 drvr = libvirt_driver.LibvirtDriver(virtapi, False)
10231
10232 instance = objects.Instance(**self.test_instance)
10233 instance.info_cache = objects.InstanceInfoCache(
10234 network_info=network_model.NetworkInfo([
10235 network_model.VIF(id=uuids.vif_1,
10236 type=network_model.VIF_TYPE_BRIDGE)]))
10237
10238 dom = fakelibvirt.Domain(drvr._get_connection(),
10239 "<domain><name>demo</name></domain>", True)
10240 guest = libvirt_guest.Guest(dom)
10241 migrate_data = objects.LibvirtLiveMigrateData(block_migration=True)
10242 disks_to_copy = (['/some/path/one', '/test/path/two'],
10243 ['vda', 'vdb'])
10244 mock_copy_disk_path.return_value = disks_to_copy
10245
10246 mock_guest.return_value = guest
10247 guest.migrate_configure_max_speed = mock.MagicMock()
10248
10249 generated_events = []
10250
10251 def fake_post():
10252 pass
10253
10254 def fake_recover():
10255 pass
10256
10257 def fake_prepare(instance, event_name):
10258 ev = mock.MagicMock(instance=instance, event_name=event_name)
10259 ev.wait.return_value = mock.MagicMock(status='completed')
10260 generated_events.append(ev)
10261 return ev
10262
10263 prepare = virtapi._compute.instance_events.prepare_for_instance_event
10264 prepare.side_effect = fake_prepare
10265
10266 drvr._live_migration(self.context, instance, "fakehost",
10267 fake_post, fake_recover, True,
10268 migrate_data)
10269 mock_copy_disk_path.assert_called_once_with(self.context, instance,
10270 guest)
10271
10272 class AnyEventletEvent(object):
10273 def __eq__(self, other):
10274 return type(other) == eventlet.event.Event
10275
10276 mock_thread.assert_called_once_with(
10277 drvr._live_migration_operation,
10278 self.context, instance, "fakehost", True,
10279 migrate_data, guest, disks_to_copy[1],
10280 libvirt_driver.MIN_MIGRATION_SPEED_BW)
10281 mock_monitor.assert_called_once_with(
10282 self.context, instance, guest, "fakehost",
10283 fake_post, fake_recover, True,
10284 migrate_data, AnyEventletEvent(), disks_to_copy[0])
10285 guest.migrate_configure_max_speed.assert_called_once_with(
10286 CONF.libvirt.live_migration_bandwidth)
10287
10288 prepare.assert_has_calls([
10289 mock.call(instance, 'network-vif-plugged-%s' % uuids.vif_1)])
10290 for event in generated_events:
10291 event.wait.assert_called_once_with()
10292
10293 @mock.patch.object(host.Host, "get_connection")
10294 @mock.patch.object(utils, "spawn")
10295 @mock.patch.object(libvirt_driver.LibvirtDriver, "_live_migration_monitor")
10296 @mock.patch.object(host.Host, "get_guest")
10297 @mock.patch.object(fakelibvirt.Connection, "_mark_running")
10298 @mock.patch.object(libvirt_driver.LibvirtDriver,
10299 "_live_migration_copy_disk_paths")
10300 def test_live_migration_ovs_vif(self, mock_copy_disk_path, mock_running,
10301 mock_guest, mock_monitor, mock_thread,
10302 mock_conn):
10303 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) 10212 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
10304 instance = objects.Instance(**self.test_instance) 10213 instance = objects.Instance(**self.test_instance)
10305 instance.info_cache = objects.InstanceInfoCache(
10306 network_info=network_model.NetworkInfo([
10307 network_model.VIF(id=uuids.vif_1,
10308 type=network_model.VIF_TYPE_OVS)]))
10309
10310 dom = fakelibvirt.Domain(drvr._get_connection(), 10214 dom = fakelibvirt.Domain(drvr._get_connection(),
10311 "<domain><name>demo</name></domain>", True) 10215 "<domain><name>demo</name></domain>", True)
10312 guest = libvirt_guest.Guest(dom) 10216 guest = libvirt_guest.Guest(dom)
@@ -10316,7 +10220,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
10316 mock_copy_disk_path.return_value = disks_to_copy 10220 mock_copy_disk_path.return_value = disks_to_copy
10317 10221
10318 mock_guest.return_value = guest 10222 mock_guest.return_value = guest
10319 guest.migrate_configure_max_speed = mock.MagicMock()
10320 10223
10321 def fake_post(): 10224 def fake_post():
10322 pass 10225 pass
@@ -10337,70 +10240,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
10337 mock_thread.assert_called_once_with( 10240 mock_thread.assert_called_once_with(
10338 drvr._live_migration_operation, 10241 drvr._live_migration_operation,
10339 self.context, instance, "fakehost", True, 10242 self.context, instance, "fakehost", True,
10340 migrate_data, guest, disks_to_copy[1], 10243 migrate_data, guest, disks_to_copy[1])
10341 CONF.libvirt.live_migration_bandwidth)
10342 mock_monitor.assert_called_once_with( 10244 mock_monitor.assert_called_once_with(
10343 self.context, instance, guest, "fakehost", 10245 self.context, instance, guest, "fakehost",
10344 fake_post, fake_recover, True, 10246 fake_post, fake_recover, True,
10345 migrate_data, AnyEventletEvent(), disks_to_copy[0]) 10247 migrate_data, AnyEventletEvent(), disks_to_copy[0])
10346 guest.migrate_configure_max_speed.assert_not_called()
10347
10348 @mock.patch.object(host.Host, "get_connection")
10349 @mock.patch.object(utils, "spawn")
10350 @mock.patch.object(libvirt_driver.LibvirtDriver, "_live_migration_monitor")
10351 @mock.patch.object(host.Host, "get_guest")
10352 @mock.patch.object(fakelibvirt.Connection, "_mark_running")
10353 @mock.patch.object(libvirt_driver.LibvirtDriver,
10354 "_live_migration_copy_disk_paths")
10355 def test_live_migration_bridge_no_events(self, mock_copy_disk_path,
10356 mock_running, mock_guest,
10357 mock_monitor, mock_thread,
10358 mock_conn):
10359 self.flags(vif_plugging_timeout=0)
10360 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
10361 instance = objects.Instance(**self.test_instance)
10362 instance.info_cache = objects.InstanceInfoCache(
10363 network_info=network_model.NetworkInfo([
10364 network_model.VIF(id=uuids.vif_1,
10365 type=network_model.VIF_TYPE_BRIDGE)]))
10366
10367 dom = fakelibvirt.Domain(drvr._get_connection(),
10368 "<domain><name>demo</name></domain>", True)
10369 guest = libvirt_guest.Guest(dom)
10370 migrate_data = objects.LibvirtLiveMigrateData(block_migration=True)
10371 disks_to_copy = (['/some/path/one', '/test/path/two'],
10372 ['vda', 'vdb'])
10373 mock_copy_disk_path.return_value = disks_to_copy
10374
10375 mock_guest.return_value = guest
10376 guest.migrate_configure_max_speed = mock.MagicMock()
10377
10378 def fake_post():
10379 pass
10380
10381 def fake_recover():
10382 pass
10383
10384 drvr._live_migration(self.context, instance, "fakehost",
10385 fake_post, fake_recover, True,
10386 migrate_data)
10387 mock_copy_disk_path.assert_called_once_with(self.context, instance,
10388 guest)
10389
10390 class AnyEventletEvent(object):
10391 def __eq__(self, other):
10392 return type(other) == eventlet.event.Event
10393
10394 mock_thread.assert_called_once_with(
10395 drvr._live_migration_operation,
10396 self.context, instance, "fakehost", True,
10397 migrate_data, guest, disks_to_copy[1],
10398 CONF.libvirt.live_migration_bandwidth)
10399 mock_monitor.assert_called_once_with(
10400 self.context, instance, guest, "fakehost",
10401 fake_post, fake_recover, True,
10402 migrate_data, AnyEventletEvent(), disks_to_copy[0])
10403 guest.migrate_configure_max_speed.assert_not_called()
10404 10248
10405 def _do_test_create_images_and_backing(self, disk_type): 10249 def _do_test_create_images_and_backing(self, disk_type):
10406 instance = objects.Instance(**self.test_instance) 10250 instance = objects.Instance(**self.test_instance)
@@ -15413,8 +15257,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
15413 15257
15414 instance = objects.Instance(vm_state=vm_states.BUILDING, 15258 instance = objects.Instance(vm_state=vm_states.BUILDING,
15415 **self.test_instance) 15259 **self.test_instance)
15416 vifs = [{'id': uuids.vif_1, 'active': False}, 15260 vifs = [{'id': 'vif1', 'active': False},
15417 {'id': uuids.vif_2, 'active': False}] 15261 {'id': 'vif2', 'active': False}]
15418 15262
15419 @mock.patch.object(drvr, 'plug_vifs') 15263 @mock.patch.object(drvr, 'plug_vifs')
15420 @mock.patch.object(drvr, 'firewall_driver') 15264 @mock.patch.object(drvr, 'firewall_driver')
@@ -15440,8 +15284,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
15440 15284
15441 if utils.is_neutron() and CONF.vif_plugging_timeout and power_on: 15285 if utils.is_neutron() and CONF.vif_plugging_timeout and power_on:
15442 prepare.assert_has_calls([ 15286 prepare.assert_has_calls([
15443 mock.call(instance, 'network-vif-plugged-%s' % uuids.vif_1), 15287 mock.call(instance, 'network-vif-plugged-vif1'),
15444 mock.call(instance, 'network-vif-plugged-%s' % uuids.vif_2)]) 15288 mock.call(instance, 'network-vif-plugged-vif2')])
15445 for event in generated_events: 15289 for event in generated_events:
15446 if neutron_failure and generated_events.index(event) != 0: 15290 if neutron_failure and generated_events.index(event) != 0:
15447 self.assertEqual(0, event.call_count) 15291 self.assertEqual(0, event.call_count)
@@ -15685,15 +15529,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
15685 {'bus': 'virtio', 'type': 'disk', 'dev': 'vdc'}) 15529 {'bus': 'virtio', 'type': 'disk', 'dev': 'vdc'})
15686 volume_save.assert_called_once_with() 15530 volume_save.assert_called_once_with()
15687 15531
15688 def test_get_neutron_events_for_live_migration(self):
15689 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
15690 network_info = [network_model.VIF(id=uuids.vif_ovs,
15691 type=network_model.VIF_TYPE_OVS),
15692 network_model.VIF(id=uuids.vif_bridge,
15693 type=network_model.VIF_TYPE_BRIDGE)]
15694 events = drvr._get_neutron_events_for_live_migration(network_info)
15695 self.assertEqual([('network-vif-plugged', uuids.vif_bridge)], events)
15696
15697 def test_get_neutron_events(self): 15532 def test_get_neutron_events(self):
15698 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) 15533 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
15699 network_info = [network_model.VIF(id='1'), 15534 network_info = [network_model.VIF(id='1'),
diff --git a/nova/tests/unit/virt/test_virt_drivers.py b/nova/tests/unit/virt/test_virt_drivers.py
index 570186a..0c32b1f 100644
--- a/nova/tests/unit/virt/test_virt_drivers.py
+++ b/nova/tests/unit/virt/test_virt_drivers.py
@@ -649,8 +649,6 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
649 649
650 def test_live_migration(self): 650 def test_live_migration(self):
651 instance_ref, network_info = self._get_running_instance() 651 instance_ref, network_info = self._get_running_instance()
652 instance_ref.info_cache = objects.InstanceInfoCache(
653 network_info=network_info)
654 fake_context = context.RequestContext('fake', 'fake') 652 fake_context = context.RequestContext('fake', 'fake')
655 migration = objects.Migration(context=fake_context, id=1) 653 migration = objects.Migration(context=fake_context, id=1)
656 migrate_data = objects.LibvirtLiveMigrateData( 654 migrate_data = objects.LibvirtLiveMigrateData(
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 03c62b1..d3f9455 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -301,8 +301,6 @@ PERF_EVENTS_CPU_FLAG_MAPPING = {'cmt': 'cmt',
301 'mbmt': 'mbm_total', 301 'mbmt': 'mbm_total',
302 } 302 }
303 303
304MIN_MIGRATION_SPEED_BW = 1 # 1 MiB/s
305
306 304
307class LibvirtDriver(driver.ComputeDriver): 305class LibvirtDriver(driver.ComputeDriver):
308 capabilities = { 306 capabilities = {
@@ -5354,12 +5352,6 @@ class LibvirtDriver(driver.ComputeDriver):
5354 if CONF.vif_plugging_is_fatal: 5352 if CONF.vif_plugging_is_fatal:
5355 raise exception.VirtualInterfaceCreateException() 5353 raise exception.VirtualInterfaceCreateException()
5356 5354
5357 def _neutron_failed_live_migration_callback(self, event_name, instance):
5358 msg = ('Neutron reported failure during live migration '
5359 'with %(event)s for instance %(uuid)s' %
5360 {'event': event_name, 'uuid': instance.uuid})
5361 raise exception.MigrationError(reason=msg)
5362
5363 def _get_neutron_events(self, network_info): 5355 def _get_neutron_events(self, network_info):
5364 # NOTE(danms): We need to collect any VIFs that are currently 5356 # NOTE(danms): We need to collect any VIFs that are currently
5365 # down that we expect a down->up event for. Anything that is 5357 # down that we expect a down->up event for. Anything that is
@@ -5369,16 +5361,6 @@ class LibvirtDriver(driver.ComputeDriver):
5369 return [('network-vif-plugged', vif['id']) 5361 return [('network-vif-plugged', vif['id'])
5370 for vif in network_info if vif.get('active', True) is False] 5362 for vif in network_info if vif.get('active', True) is False]
5371 5363
5372 def _get_neutron_events_for_live_migration(self, network_info):
5373 # Neutron should send events to Nova indicating that the VIFs
5374 # are successfully plugged on destination host.
5375
5376 # TODO(sahid): Currently we only use the mechanism of waiting
5377 # for neutron events during live-migration for linux-bridge.
5378 return [('network-vif-plugged', vif['id'])
5379 for vif in network_info if (
5380 vif.get('type') == network_model.VIF_TYPE_BRIDGE)]
5381
5382 def _cleanup_failed_start(self, context, instance, network_info, 5364 def _cleanup_failed_start(self, context, instance, network_info,
5383 block_device_info, guest, destroy_disks): 5365 block_device_info, guest, destroy_disks):
5384 try: 5366 try:
@@ -6462,7 +6444,7 @@ class LibvirtDriver(driver.ComputeDriver):
6462 6444
6463 def _live_migration_operation(self, context, instance, dest, 6445 def _live_migration_operation(self, context, instance, dest,
6464 block_migration, migrate_data, guest, 6446 block_migration, migrate_data, guest,
6465 device_names, bandwidth): 6447 device_names):
6466 """Invoke the live migration operation 6448 """Invoke the live migration operation
6467 6449
6468 :param context: security context 6450 :param context: security context
@@ -6475,7 +6457,6 @@ class LibvirtDriver(driver.ComputeDriver):
6475 :param guest: the guest domain object 6457 :param guest: the guest domain object
6476 :param device_names: list of device names that are being migrated with 6458 :param device_names: list of device names that are being migrated with
6477 instance 6459 instance
6478 :param bandwidth: MiB/s of bandwidth allowed for the migration at start
6479 6460
6480 This method is intended to be run in a background thread and will 6461 This method is intended to be run in a background thread and will
6481 block that thread until the migration is finished or failed. 6462 block that thread until the migration is finished or failed.
@@ -6549,7 +6530,7 @@ class LibvirtDriver(driver.ComputeDriver):
6549 flags=migration_flags, 6530 flags=migration_flags,
6550 params=params, 6531 params=params,
6551 domain_xml=new_xml_str, 6532 domain_xml=new_xml_str,
6552 bandwidth=bandwidth) 6533 bandwidth=CONF.libvirt.live_migration_bandwidth)
6553 6534
6554 for hostname, port in serial_ports: 6535 for hostname, port in serial_ports:
6555 serial_console.release_port(host=hostname, port=port) 6536 serial_console.release_port(host=hostname, port=port)
@@ -6891,58 +6872,11 @@ class LibvirtDriver(driver.ComputeDriver):
6891 disk_paths, device_names = self._live_migration_copy_disk_paths( 6872 disk_paths, device_names = self._live_migration_copy_disk_paths(
6892 context, instance, guest) 6873 context, instance, guest)
6893 6874
6894 deadline = CONF.vif_plugging_timeout 6875 opthread = utils.spawn(self._live_migration_operation,
6895 if utils.is_neutron() and deadline: 6876 context, instance, dest,
6896 # We don't generate events if CONF.vif_plugging_timeout=0 6877 block_migration,
6897 # meaning that the operator disabled using them. 6878 migrate_data, guest,
6898 6879 device_names)
6899 # In case of Linux Bridge, the agent is waiting for new
6900 # TAP devices on destination node. They are going to be
6901 # created by libvirt at the very beginning of the
6902 # live-migration process. Then receiving the events from
6903 # Neutron will ensure that everything is configured
6904 # correctly.
6905 events = self._get_neutron_events_for_live_migration(
6906 instance.get_network_info())
6907 else:
6908 # TODO(sahid): This 'is_neutron()' condition should be
6909 # removed when nova-network will be erased from the tree
6910 # (Rocky).
6911 events = []
6912
6913 if events:
6914 # We start migration with the minimum bandwidth
6915 # speed. Depending on the VIF type (see:
6916 # _get_neutron_events_for_live_migration) we will wait for
6917 # Neutron to send events that confirm network is setup or
6918 # directly configure QEMU to use the maximun BW allowed.
6919 bandwidth = MIN_MIGRATION_SPEED_BW
6920 else:
6921 bandwidth = CONF.libvirt.live_migration_bandwidth
6922
6923 try:
6924 error_cb = self._neutron_failed_live_migration_callback
6925 with self.virtapi.wait_for_instance_event(instance, events,
6926 deadline=deadline,
6927 error_callback=error_cb):
6928 opthread = utils.spawn(self._live_migration_operation,
6929 context, instance, dest,
6930 block_migration,
6931 migrate_data, guest,
6932 device_names, bandwidth)
6933 except eventlet.timeout.Timeout:
6934 msg = ('Timeout waiting for VIF plugging events, '
6935 'canceling migration')
6936 raise exception.MigrationError(reason=msg)
6937 else:
6938 if utils.is_neutron() and events:
6939 LOG.debug('VIF events received, continuing migration '
6940 'with max bandwidth configured: %d',
6941 CONF.libvirt.live_migration_bandwidth,
6942 instance=instance)
6943 # Configure QEMU to use the maximum bandwidth allowed.
6944 guest.migrate_configure_max_speed(
6945 CONF.libvirt.live_migration_bandwidth)
6946 6880
6947 finish_event = eventlet.event.Event() 6881 finish_event = eventlet.event.Event()
6948 self.active_migrations[instance.uuid] = deque() 6882 self.active_migrations[instance.uuid] = deque()
diff --git a/releasenotes/notes/bug-1414559-880d6b3c1ce3b95e.yaml b/releasenotes/notes/bug-1414559-880d6b3c1ce3b95e.yaml
deleted file mode 100644
index 0a760d4..0000000
--- a/releasenotes/notes/bug-1414559-880d6b3c1ce3b95e.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
1---
2upgrade:
3 - |
4 Live migrations are now initially slowed to ensure Neutron is given
5 adequate time to wire up the VIFs on the destination. Once complete Neutron
6 will send an event to Nova returning the migration to full speed. This
7 requires Neutron >=11.0.4 on Pike when used with LinuxBridge VIFs in order
8 to pick up the Icb039ae2d465e3822ab07ae4f9bc405c1362afba bugfix.