VNX: add option vnx_async_migrate

Before this fix, customers can disable async migration only by passing
`--metadata async_migrate=False` in volumes metadata. This fix adds an
option named `vnx_async_migrate` which could help set the default value
of async migration for whole backend. If customers don't pass in the
`async_migrate` in metadata, the value of this option will be used.

Change-Id: I8e59039da78ecc9fb5415a10ff2a7c26ee689171
Closes-bug: #1796825
This commit is contained in:
Ryan Liang 2019-02-26 17:12:27 +08:00
parent 698b522a57
commit 3ecdc2bfc8
8 changed files with 66 additions and 12 deletions

View File

@ -573,6 +573,9 @@ test_calc_migrate_and_provision_image_cache:
test_calc_migrate_and_provision:
volume: *volume_base
test_calc_migrate_and_provision_default:
volume: *volume_base
test_get_backend_qos_specs:
volume:
_type: 'volume'

View File

@ -205,6 +205,18 @@ class TestUtils(test_base.TestCase):
async_migrate)
self.assertEqual(provision.name, 'THICK')
@res_mock.mock_driver_input
def test_calc_migrate_and_provision_default(self, mocked):
volume = mocked['volume']
volume.display_name = 'volume-ca86b9a0-d0d5-4267-8cd5-c62274056cc0'
async_migrate, provision = vnx_utils.calc_migrate_and_provision(
volume, default_async_migrate=False)
self.assertFalse(async_migrate)
self.assertEqual(provision.name, 'THICK')
async_migrate, provision = vnx_utils.calc_migrate_and_provision(
volume, default_async_migrate=True)
self.assertTrue(async_migrate)
@ut_utils.patch_extra_specs({})
@res_mock.mock_driver_input
def test_get_backend_qos_specs(self, cinder_input):

View File

@ -67,6 +67,7 @@ class CommonAdapter(replication.ReplicationAdapter):
self.destroy_empty_sg = None
self.itor_auto_dereg = None
self.queue_path = None
self.async_migrate = None
def _build_client_from_config(self, config, queue_path=None):
return client.Client(
@ -104,6 +105,7 @@ class CommonAdapter(replication.ReplicationAdapter):
self.protocol = self.config.storage_protocol
self.destroy_empty_sg = self.config.destroy_empty_storage_group
self.itor_auto_dereg = self.config.initiator_auto_deregistration
self.async_migrate = self.config.vnx_async_migrate
self.set_extra_spec_defaults()
def _normalize_config(self):
@ -349,7 +351,8 @@ class CommonAdapter(replication.ReplicationAdapter):
volume_metadata['snapcopy'] = 'True'
volume_metadata['async_migrate'] = 'False'
else:
async_migrate, provision = utils.calc_migrate_and_provision(volume)
async_migrate, provision = utils.calc_migrate_and_provision(
volume, default_async_migrate=self.async_migrate)
new_snap_name = (
utils.construct_snap_name(volume) if async_migrate else None)
new_lun_id = emc_taskflow.create_volume_from_snapshot(
@ -404,7 +407,8 @@ class CommonAdapter(replication.ReplicationAdapter):
volume_metadata['snapcopy'] = 'True'
volume_metadata['async_migrate'] = 'False'
else:
async_migrate, provision = utils.calc_migrate_and_provision(volume)
async_migrate, provision = utils.calc_migrate_and_provision(
volume, default_async_migrate=self.async_migrate)
new_lun_id = emc_taskflow.create_cloned_volume(
client=self.client,
snap_name=snap_name,
@ -779,7 +783,8 @@ class CommonAdapter(replication.ReplicationAdapter):
def delete_volume(self, volume):
"""Deletes an EMC volume."""
async_migrate = utils.is_async_migrate_enabled(volume)
async_migrate = utils.is_async_migrate_enabled(
volume, default=self.async_migrate)
snap_copy = (utils.construct_snap_name(volume) if
utils.is_snapcopy_enabled(volume) else None)
self.cleanup_lun_replication(volume)

View File

@ -109,7 +109,17 @@ VNX_OPTS = [
default=False,
help='Force LUN creation even if '
'the full threshold of pool is reached. '
'By default, the value is False.')
'By default, the value is False.'),
cfg.BoolOpt('vnx_async_migrate',
default=True,
help='Always use asynchronous migration during volume cloning '
'and creating from snapshot. As described in '
'configuration doc, async migration has some '
'constraints. Besides using metadata, customers could '
'use this option to disable async migration. Be aware '
'that `async_migrate` in metadata overrides this '
'option when both are set. By default, the value is True.'
)
]
CONF.register_opts(VNX_OPTS, group=configuration.SHARED_CONF_GROUP)

View File

@ -86,9 +86,11 @@ class VNXDriver(driver.ManageableVD,
under `destroy_empty_stroage_group` setting to `True`
14.0.0 - Fix bug 1794646: failed to delete LUNs from backend due to
the temporary snapshots on them wasn't deleted.
14.0.1 - Fix bug 1796825, add an option to set default value for
`async_migrate`.
"""
VERSION = '14.00.00'
VERSION = '14.00.01'
VENDOR = 'Dell EMC'
# ThirdPartySystems wiki page
CI_WIKI_NAME = "EMC_VNX_CI"

View File

@ -257,7 +257,7 @@ def is_snapcopy_enabled(volume):
return 'snapcopy' in meta and meta['snapcopy'].lower() == 'true'
def is_async_migrate_enabled(volume):
def is_async_migrate_enabled(volume, default=True):
extra_specs = common.ExtraSpecs.from_volume(volume)
if extra_specs.is_replication_enabled:
# For replication-enabled volume, we should not use the async-cloned
@ -266,8 +266,7 @@ def is_async_migrate_enabled(volume):
return False
meta = get_metadata(volume)
if 'async_migrate' not in meta:
# Asynchronous migration is the default behavior now
return True
return default
return 'async_migrate' in meta and meta['async_migrate'].lower() == 'true'
@ -441,7 +440,7 @@ def is_image_cache_volume(volume):
return False
def calc_migrate_and_provision(volume):
def calc_migrate_and_provision(volume, default_async_migrate=True):
"""Returns a tuple of async migrate and provision type.
The first element is the flag whether to enable async migrate,
@ -451,7 +450,8 @@ def calc_migrate_and_provision(volume):
return False, storops.VNXProvisionEnum.THIN
else:
specs = common.ExtraSpecs.from_volume(volume)
return is_async_migrate_enabled(volume), specs.provision
return (is_async_migrate_enabled(volume, default_async_migrate),
specs.provision)
def get_backend_qos_specs(volume):

View File

@ -433,6 +433,16 @@ Ignore pool full threshold
If ``ignore_pool_full_threshold`` is set to ``True``, driver will force LUN
creation even if the full threshold of pool is reached. Default to ``False``.
Default value for async migration
---------------------------------
Option ``vnx_async_migrate`` is used to set the default value of async
migration for the backend. The default value of this option is `True` if it
isn't set in ``cinder.conf`` to preserve compatibility. If ``async_migrate`` is
not set in metadata of volume, the value of this option will be used.
Otherwise, ``async_migrate`` value in metadata will override the value of this
option. For more detail, refer to `asynchronous migration support`_.
Extra spec options
~~~~~~~~~~~~~~~~~~
@ -791,8 +801,14 @@ as the default cloning method. The driver will return immediately after the
migration session starts on the VNX, which dramatically reduces the time before
a volume is available for use.
To disable this feature, user can add ``--metadata async_migrate=False`` when
creating new volume from source.
To disable this feature, user needs to do any one of below actions:
- Configure ``vnx_async_migrate = False`` for the backend in ``cinder.conf``,
then restart Cinder services.
- Add ``--metadata async_migrate=False`` when creating new volume from source.
Be aware, ``async_migrate`` in metadata overrides the option
``vnx_async_migrate`` when both are set.
**Constraints**

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Dell EMC VNX Driver: Fix `bug 1796825
<https://bugs.launchpad.net/cinder/+bug/1796825>`__, adding an option named
`vnx_async_migrate` to accept the default setting for async migration.