Storwize: get list of all volumes for ensure_export.

This patch solves the problem of too slow initialization of
cinder-volume service.
Previously lsvdisk() was called separately for each 'in-use' volume
in order to check if the volume exists on the storage.
Now lsvdisk() is called once per pool.

Change-Id: Ia84afc12a30ea7b714b287844e81ba02ce4b0f3d
Closes-Bug: #1749687
This commit is contained in:
Margarita Shakhova 2018-02-21 07:50:47 +03:00
parent 1aa9231cb2
commit d5f79c52d8
3 changed files with 59 additions and 2 deletions

View File

@ -1907,6 +1907,15 @@ port_speed!N/A
return ('', '') return ('', '')
def _cmd_lsvdisks_from_filter(self, filter_name, value):
volumes = []
if filter_name == 'mdisk_grp_name':
for vol in self._volumes_list:
vol_info = self._volumes_list[vol]
if vol_info['mdisk_grp_name'] == value:
volumes.append(vol)
return volumes
def _cmd_chvdisk(self, **kwargs): def _cmd_chvdisk(self, **kwargs):
if 'obj' not in kwargs: if 'obj' not in kwargs:
return self._errors['CMMVC5701E'] return self._errors['CMMVC5701E']
@ -4799,6 +4808,26 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput, self.assertRaises(exception.InvalidInput,
self._driver._validate_pools_exist) self._driver._validate_pools_exist)
def _get_pool_volumes(self, pool):
vdisks = self.sim._cmd_lsvdisks_from_filter('mdisk_grp_name', pool)
return vdisks
def test_get_all_volumes(self):
_volumes_list = []
pools = _get_test_pool(get_all=True)
for pool in pools:
host = 'openstack@svc#%s' % pool
vol1 = testutils.create_volume(self.ctxt, host=host)
self.driver.create_volume(vol1)
vol2 = testutils.create_volume(self.ctxt, host=host)
self.driver.create_volume(vol2)
for pool in pools:
pool_vols = self._get_pool_volumes(pool)
for pool_vol in pool_vols:
_volumes_list.append(pool_vol)
for vol in _volumes_list:
self.assertIn(vol, self.sim._volumes_list)
def _create_volume_type(self, opts, type_name): def _create_volume_type(self, opts, type_name):
type_ref = volume_types.create(self.ctxt, type_name, opts) type_ref = volume_types.create(self.ctxt, type_name, opts)
vol_type = objects.VolumeType.get_by_id(self.ctxt, type_ref['id']) vol_type = objects.VolumeType.get_by_id(self.ctxt, type_ref['id'])

View File

@ -810,6 +810,11 @@ class StorwizeHelpers(object):
return True return True
return False return False
def get_pool_volumes(self, pool):
"""Return volumes for the specified pool."""
vdisks = self.ssh.lsvdisks_from_filter('mdisk_grp_name', pool)
return vdisks.result
def get_available_io_groups(self): def get_available_io_groups(self):
"""Return list of available IO groups.""" """Return list of available IO groups."""
iogrps = [] iogrps = []
@ -2682,6 +2687,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
} }
self._active_backend_id = kwargs.get('active_backend_id') self._active_backend_id = kwargs.get('active_backend_id')
# This list is used to ensure volume export
self._volumes_list = []
# This dictionary is used to map each replication target to certain # This dictionary is used to map each replication target to certain
# replication manager object. # replication manager object.
self.replica_manager = {} self.replica_manager = {}
@ -2714,6 +2722,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
# Validate that the pool exists # Validate that the pool exists
self._validate_pools_exist() self._validate_pools_exist()
# Get list of all volumes
self._get_all_volumes()
# Build the list of in-progress vdisk copy operations # Build the list of in-progress vdisk copy operations
if ctxt is None: if ctxt is None:
admin_context = context.get_admin_context() admin_context = context.get_admin_context()
@ -2783,6 +2794,14 @@ class StorwizeSVCCommonDriver(san.SanDriver,
reason = (_('Failed getting details for pool %s.') % pool) reason = (_('Failed getting details for pool %s.') % pool)
raise exception.InvalidInput(reason=reason) raise exception.InvalidInput(reason=reason)
def _get_all_volumes(self):
# Get list of all volumes
pools = self._get_backend_pools()
for pool in pools:
pool_vols = self._helpers.get_pool_volumes(pool)
for volume in pool_vols:
self._volumes_list.append(volume['name'])
def check_for_setup_error(self): def check_for_setup_error(self):
"""Ensure that the flags are set properly.""" """Ensure that the flags are set properly."""
LOG.debug('enter: check_for_setup_error') LOG.debug('enter: check_for_setup_error')
@ -2954,8 +2973,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
The system does not "export" volumes as a Linux iSCSI target does, The system does not "export" volumes as a Linux iSCSI target does,
and therefore we just check that the volume exists on the storage. and therefore we just check that the volume exists on the storage.
""" """
vol_name = self._get_target_vol(volume) volume_defined = volume['name'] in self._volumes_list
volume_defined = self._helpers.is_vdisk_defined(vol_name)
if not volume_defined: if not volume_defined:
LOG.error('ensure_export: Volume %s not found on storage.', LOG.error('ensure_export: Volume %s not found on storage.',

View File

@ -0,0 +1,10 @@
fixes:
- |
Storwize SVC Driver: Fixes `bug 1749687
<https://bugs.launchpad.net/cinder/+bug/1749687>`__
previously lsvdisk() was called separately for every
'in-use' volume in order to check if the volume exists
on the storage.
In order to avoid problem of too long driver initialization
now lsvdisk() is called once per pool.