bug 899767: fix vif-plugging with live migration

Expose vif_unplug method in virt layer, as the compute manager has to
explicitly call it on during live migration, so that network devices are
torn down even if the disk image is not.

Change-Id: Iae88c72f4fd2c7c097c23ef9e5f8fd392052f73e
This commit is contained in:
Dan Wendlandt
2011-12-12 10:34:33 -08:00
parent b43fa8b590
commit 6b6633521c
9 changed files with 50 additions and 9 deletions

View File

@@ -1735,6 +1735,12 @@ class ComputeManager(manager.SchedulerDependentManager):
# must be deleted for preparing next block migration
if block_migration:
self.driver.destroy(instance_ref, network_info)
else:
# self.driver.destroy() usually performs vif unplugging
# but we must do it explicitly here when block_migration
# is false, as the network devices at the source must be
# torn down
self.driver.unplug_vifs(instance_ref, network_info)
LOG.info(_('Migrating %(i_name)s to %(dest)s finished successfully.')
% locals())

View File

@@ -1022,6 +1022,8 @@ class ComputeTestCase(BaseTestCase):
rpc.call(c, db.queue_get_for(c, FLAGS.compute_topic, dest),
{"method": "post_live_migration_at_destination",
"args": {'instance_id': i_ref['id'], 'block_migration': False}})
self.mox.StubOutWithMock(self.compute.driver, 'unplug_vifs')
self.compute.driver.unplug_vifs(i_ref, [])
# start test
self.mox.ReplayAll()

View File

@@ -516,10 +516,14 @@ class ComputeDriver(object):
raise NotImplementedError()
def plug_vifs(self, instance, network_info):
"""Plugs in VIFs to networks."""
"""Plug VIFs into networks."""
# TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError()
def unplug_vifs(self, instance, network_info):
"""Unplug VIFs from networks."""
raise NotImplementedError()
def update_host_status(self):
"""Refresh host stats"""
raise NotImplementedError()

View File

@@ -94,7 +94,11 @@ class FakeConnection(driver.ComputeDriver):
return info_list
def plug_vifs(self, instance, network_info):
"""Plugin VIFs into networks."""
"""Plug VIFs into networks."""
pass
def unplug_vifs(self, instance, network_info):
"""Unplug VIFs from networks."""
pass
def spawn(self, context, instance, image_meta,

View File

@@ -516,3 +516,11 @@ class HyperVConnection(driver.ComputeDriver):
def set_host_enabled(self, host, enabled):
"""Sets the specified host's ability to accept new instances."""
pass
def plug_vifs(self, instance, network_info):
"""Plug VIFs into networks."""
pass
def unplug_vifs(self, instance, network_info):
"""Unplug VIFs from networks."""
pass

View File

@@ -290,10 +290,15 @@ class LibvirtConnection(driver.ComputeDriver):
return infos
def plug_vifs(self, instance, network_info):
"""Plugin VIFs into networks."""
"""Plug VIFs into networks."""
for (network, mapping) in network_info:
self.vif_driver.plug(instance, network, mapping)
def unplug_vifs(self, instance, network_info):
"""Unplug VIFs from networks."""
for (network, mapping) in network_info:
self.vif_driver.unplug(instance, network, mapping)
def destroy(self, instance, network_info, block_device_info=None,
cleanup=True):
instance_name = instance['name']
@@ -350,8 +355,7 @@ class LibvirtConnection(driver.ComputeDriver):
locals())
raise
for (network, mapping) in network_info:
self.vif_driver.unplug(instance, network, mapping)
self.unplug_vifs(instance, network_info)
def _wait_for_destroy():
"""Called at an interval until the VM is gone."""
@@ -545,6 +549,7 @@ class LibvirtConnection(driver.ComputeDriver):
# better because we cannot ensure flushing dirty buffers
# in the guest OS. But, in case of KVM, shutdown() does not work...
self.destroy(instance, network_info, cleanup=False)
self.unplug_vifs(instance, network_info)
self.plug_vifs(instance, network_info)
self.firewall_driver.setup_basic_filtering(instance, network_info)
self.firewall_driver.prepare_instance_filter(instance, network_info)

View File

@@ -201,9 +201,13 @@ class VMWareESXConnection(driver.ComputeDriver):
pass
def plug_vifs(self, instance, network_info):
"""Plugs in VIFs to networks."""
"""Plug VIFs into networks."""
self._vmops.plug_vifs(instance, network_info)
def unplug_vifs(self, instance, network_info):
"""Unplug VIFs from networks."""
self._vmops.unplug_vifs(instance, network_info)
class VMWareAPISession(object):
"""

View File

@@ -1139,9 +1139,7 @@ class VMOps(object):
self._destroy_kernel_ramdisk(instance, vm_ref)
self._destroy_vm(instance, vm_ref)
if network_info:
for (network, mapping) in network_info:
self.vif_driver.unplug(instance, network, mapping)
self.unplug_vifs(instance, network_info)
def pause(self, instance):
"""Pause VM instance."""
@@ -1459,6 +1457,11 @@ class VMOps(object):
for (network, mapping) in network_info:
self.vif_driver.plug(self._session, instance, network, mapping)
def unplug_vifs(self, instance, network_info):
if network_info:
for (network, mapping) in network_info:
self.vif_driver.unplug(instance, network, mapping)
def reset_network(self, instance, vm_ref=None):
"""Creates uuid arg to pass to make_agent_call and calls it."""
if not vm_ref:

View File

@@ -297,8 +297,13 @@ class XenAPIConnection(driver.ComputeDriver):
self._vmops.inject_network_info(instance, network_info)
def plug_vifs(self, instance_ref, network_info):
"""Plug VIFs into networks."""
self._vmops.plug_vifs(instance_ref, network_info)
def unplug_vifs(self, instance_ref, network_info):
"""Unplug VIFs from networks."""
self._vmops.unplug_vifs(instance_ref, network_info)
def get_info(self, instance_name):
"""Return data about VM instance"""
return self._vmops.get_info(instance_name)