libvirt: force config related migration flags

The Nova libvirt driver relies on libvirt deleting the configuration
from the source host at the end of the migration, otherwise the
VM remains on the source host in a "shut off" state ... except in
the case of block migration, where the cleanup code path does actually
delete the VM's libvirt config.

If the Nova code assume's that VIR_MIGRATE_UNDEFINE_SOURCE is set,
there's really no sense in allowing users to configure without it.

Similarly, the driver explicitly saves the VM configuration on the
destination host, so it makes no sense to allow users to configure
the VIR_MIGRATE_PERSIST_DEST flag.

Change-Id: Ibeb35590fd83f2190c9c9cb16128e9e2628b38cd
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
This commit is contained in:
Mark McLoughlin 2016-01-04 20:11:08 +00:00
parent 53eedc2df4
commit 3fd24ba528
4 changed files with 49 additions and 1 deletions

View File

@ -91,6 +91,7 @@ VIR_CRED_EXTERNAL = 9
VIR_MIGRATE_LIVE = 1
VIR_MIGRATE_PEER2PEER = 2
VIR_MIGRATE_TUNNELLED = 4
VIR_MIGRATE_PERSIST_DEST = 8
VIR_MIGRATE_UNDEFINE_SOURCE = 16
VIR_MIGRATE_NON_SHARED_INC = 128

View File

@ -991,6 +991,37 @@ class LibvirtConnTestCase(test.NoDBTestCase):
msg = mock_log.warning.call_args_list[1]
self.assertIn('Removing the VIR_MIGRATE_PEER2PEER flag', msg[0][0])
@mock.patch('nova.virt.libvirt.driver.LOG')
def test_parse_migration_flags_config_mgmt(self, mock_log):
self._do_test_parse_migration_flags(
lm_config=('VIR_MIGRATE_PERSIST_DEST, '
'VIR_MIGRATE_PEER2PEER, '
'VIR_MIGRATE_LIVE, '
'VIR_MIGRATE_TUNNELLED'),
bm_config=('VIR_MIGRATE_PERSIST_DEST, '
'VIR_MIGRATE_PEER2PEER, '
'VIR_MIGRATE_LIVE, '
'VIR_MIGRATE_TUNNELLED, '
'VIR_MIGRATE_NON_SHARED_INC'),
lm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_TUNNELLED),
bm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_TUNNELLED |
libvirt_driver.libvirt.VIR_MIGRATE_NON_SHARED_INC))
msg = mock_log.warning.call_args_list[0]
self.assertIn('Adding the VIR_MIGRATE_UNDEFINE_SOURCE flag', msg[0][0])
msg = mock_log.warning.call_args_list[1]
self.assertIn('Removing the VIR_MIGRATE_PERSIST_DEST flag', msg[0][0])
msg = mock_log.warning.call_args_list[2]
self.assertIn('Adding the VIR_MIGRATE_UNDEFINE_SOURCE flag', msg[0][0])
msg = mock_log.warning.call_args_list[3]
self.assertIn('Removing the VIR_MIGRATE_PERSIST_DEST flag', msg[0][0])
@mock.patch('nova.utils.get_image_from_system_metadata')
@mock.patch.object(host.Host,
'has_min_version', return_value=True)

View File

@ -659,6 +659,20 @@ class LibvirtDriver(driver.ComputeDriver):
'virt_type': CONF.libvirt.virt_type})
migration_flags |= libvirt.VIR_MIGRATE_PEER2PEER
if (migration_flags & libvirt.VIR_MIGRATE_UNDEFINE_SOURCE) == 0:
LOG.warning(_LW('Adding the VIR_MIGRATE_UNDEFINE_SOURCE flag to '
'%(config_name)s because, without it, migrated '
'VMs will remain defined on the source host'),
{'config_name': config_name})
migration_flags |= libvirt.VIR_MIGRATE_UNDEFINE_SOURCE
if (migration_flags & libvirt.VIR_MIGRATE_PERSIST_DEST) != 0:
LOG.warning(_LW('Removing the VIR_MIGRATE_PERSIST_DEST flag from '
'%(config_name)s as Nova ensures the VM is '
'persisted on the destination host'),
{'config_name': config_name})
migration_flags &= ~libvirt.VIR_MIGRATE_PERSIST_DEST
return migration_flags
def _check_block_migration_flags(self, live_migration_flags,

View File

@ -6,5 +6,7 @@ upgrade:
contain VIR_MIGRATE_SHARED_INC but block_migration_flag
must contain it. Both options must contain the
VIR_MIGRATE_PEER2PEER, except when using the 'xen' virt
type this flag is not supported.
type this flag is not supported. Both flags must contain
the VIR_MIGRATE_UNDEFINE_SOURCE flag and not contain the
VIR_MIGRATE_PERSIST_DEST flag.