libvirt: add a new live_migration_tunnelled config

Add a config option which explicitly controls whether we pass the
VIR_MIGRATE_TUNNELLED flag to libvirt. This is a lot more covenient
than having users modify a list of obscure flags.

Note that this especially makes sense as part of a longer term plan
to remove the live_migration_flag and block_migration_flag config
options completely, and instead have config options for controlling
specific behavior choices that operators care about.

Note also that review Id8b38b0978cdc80df37cb26bb69d8f4bec5bf766
essentially proposes changing the default of this config value
to false.

DocImpact

Change-Id: I8d77596860a7803f8549cde4277e9a0509e4675a
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
This commit is contained in:
Mark McLoughlin 2016-01-04 20:11:18 +00:00
parent 3fd24ba528
commit 621594fc41
3 changed files with 94 additions and 0 deletions

View File

@ -1022,6 +1022,53 @@ class LibvirtConnTestCase(test.NoDBTestCase):
msg = mock_log.warning.call_args_list[3]
self.assertIn('Removing the VIR_MIGRATE_PERSIST_DEST flag', msg[0][0])
@mock.patch('nova.virt.libvirt.driver.LOG')
def test_live_migration_tunnelled_true(self, mock_log):
self.flags(live_migration_tunnelled=True, group='libvirt')
self._do_test_parse_migration_flags(
lm_config=('VIR_MIGRATE_PEER2PEER, VIR_MIGRATE_UNDEFINE_SOURCE, '
'VIR_MIGRATE_LIVE'),
bm_config=('VIR_MIGRATE_PEER2PEER, VIR_MIGRATE_UNDEFINE_SOURCE, '
'VIR_MIGRATE_LIVE, VIR_MIGRATE_NON_SHARED_INC'),
lm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
libvirt_driver.libvirt.VIR_MIGRATE_TUNNELLED),
bm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
libvirt_driver.libvirt.VIR_MIGRATE_NON_SHARED_INC |
libvirt_driver.libvirt.VIR_MIGRATE_TUNNELLED))
msg = mock_log.warning.call_args_list[0]
self.assertIn('does not contain the VIR_MIGRATE_TUNNELLED', msg[0][0])
msg = mock_log.warning.call_args_list[1]
self.assertIn('does not contain the VIR_MIGRATE_TUNNELLED', msg[0][0])
@mock.patch('nova.virt.libvirt.driver.LOG')
def test_live_migration_tunnelled_false(self, mock_log):
self.flags(live_migration_tunnelled=False, group='libvirt')
self._do_test_parse_migration_flags(
lm_config=('VIR_MIGRATE_PEER2PEER, VIR_MIGRATE_UNDEFINE_SOURCE, '
'VIR_MIGRATE_LIVE, VIR_MIGRATE_TUNNELLED'),
bm_config=('VIR_MIGRATE_PEER2PEER, VIR_MIGRATE_UNDEFINE_SOURCE, '
'VIR_MIGRATE_LIVE, VIR_MIGRATE_NON_SHARED_INC, '
'VIR_MIGRATE_TUNNELLED'),
lm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE),
bm_expected=(libvirt_driver.libvirt.VIR_MIGRATE_LIVE |
libvirt_driver.libvirt.VIR_MIGRATE_PEER2PEER |
libvirt_driver.libvirt.VIR_MIGRATE_UNDEFINE_SOURCE |
libvirt_driver.libvirt.VIR_MIGRATE_NON_SHARED_INC))
msg = mock_log.warning.call_args_list[0]
self.assertIn('contains the VIR_MIGRATE_TUNNELLED flag', msg[0][0])
msg = mock_log.warning.call_args_list[1]
self.assertIn('contains the VIR_MIGRATE_TUNNELLED 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

@ -168,6 +168,16 @@ libvirt_opts = [
'VIR_MIGRATE_LIVE, VIR_MIGRATE_TUNNELLED, '
'VIR_MIGRATE_NON_SHARED_INC',
help='Migration flags to be set for block migration'),
cfg.BoolOpt('live_migration_tunnelled',
help='Whether to use tunnelled migration, where migration '
'data is transported over the libvirtd connection. If '
'True, we use the VIR_MIGRATE_TUNNELLED migration flag, '
'avoiding the need to configure the network to allow '
'direct hypervisor to hypervisor communication. If '
'False, use the native transport. If not set, Nova '
'will choose a sensible default based on, for example '
'the availability of native encryption support in the '
'hypervisor.'),
cfg.IntOpt('live_migration_bandwidth',
default=0,
help='Maximum bandwidth(in MiB/s) to be used during migration. '
@ -693,6 +703,31 @@ class LibvirtDriver(driver.ComputeDriver):
return (live_migration_flags, block_migration_flags)
def _handle_live_migration_tunnelled(self, migration_flags, config_name):
if CONF.libvirt.live_migration_tunnelled is None:
return migration_flags
if CONF.libvirt.live_migration_tunnelled:
if (migration_flags & libvirt.VIR_MIGRATE_TUNNELLED) == 0:
LOG.warning(_LW('The %(config_name)s config option does not '
'contain the VIR_MIGRATE_TUNNELLED flag but '
'the live_migration_tunnelled is set to True '
'which causes VIR_MIGRATE_TUNNELLED to be '
'set'),
{'config_name': config_name})
migration_flags |= libvirt.VIR_MIGRATE_TUNNELLED
else:
if (migration_flags & libvirt.VIR_MIGRATE_TUNNELLED) != 0:
LOG.warning(_LW('The %(config_name)s config option contains '
'the VIR_MIGRATE_TUNNELLED flag but the '
'live_migration_tunnelled is set to False '
'which causes VIR_MIGRATE_TUNNELLED to be '
'unset'),
{'config_name': config_name})
migration_flags &= ~libvirt.VIR_MIGRATE_TUNNELLED
return migration_flags
def _parse_migration_flags(self):
def str2sum(str_val):
logical_sum = 0
@ -719,6 +754,11 @@ class LibvirtDriver(driver.ComputeDriver):
block_migration_flags) = self._check_block_migration_flags(
live_migration_flags, block_migration_flags)
live_migration_flags = self._handle_live_migration_tunnelled(
live_migration_flags, live_config_name)
block_migration_flags = self._handle_live_migration_tunnelled(
block_migration_flags, block_config_name)
self._live_migration_flags = live_migration_flags
self._block_migration_flags = block_migration_flags

View File

@ -0,0 +1,7 @@
---
features:
- The libvirt driver now has a live_migration_tunnelled
configuration option which should be used where the
VIR_MIGRATE_TUNNELLED flag would previously have been
set or unset in the live_migration_flag and
block_migration_flag configuration options.